6

我正在尝试使用 tvOS,但我对处理 json 调用有一个小问题。我必须通过 API 获取一些数据,假设为了测试,我正在调用这个链接

http://query.yahooapis.com/v1/public/yql?q=select%20item%20from%20weather.forecast%20where%20location%3D%223015%22&format=json

我试图通过一些修改来使用这个功能

function getDocument(url) {
  var templateXHR = new XMLHttpRequest();
  templateXHR.responseType = "json";
  templateXHR.open("GET", url, true);
  templateXHR.send();
  return templateXHR;
}

但没有成功。任何提示或帮助?

如果我需要使用 NodeJS,我该怎么做?

4

6 回答 6

4

这是我开始工作的一个。它在许多方面并不理想,但向您展示了一些可以开始的东西。

function jsonRequest(options) {

  var url = options.url;
  var method = options.method || 'GET';
  var headers = options.headers || {} ;
  var body = options.body || '';
  var callback = options.callback || function(err, data) {
    console.error("options.callback was missing for this request");
  };

  if (!url) {
    throw 'loadURL requires a url argument';
  }

  var xhr = new XMLHttpRequest();
  xhr.responseType = 'json';
  xhr.onreadystatechange = function() {
    try {
      if (xhr.readyState === 4) {
        if (xhr.status === 200) {
          callback(null, JSON.parse(xhr.responseText));
        } else {
          callback(new Error("Error [" + xhr.status + "] making http request: " + url));
        }
      }
    } catch (err) {
      console.error('Aborting request ' + url + '. Error: ' + err);
      xhr.abort();
      callback(new Error("Error making request to: " + url + " error: " + err));
    }
  };

  xhr.open(method, url, true);

  Object.keys(headers).forEach(function(key) {
    xhr.setRequestHeader(key, headers[key]);
  });

  xhr.send();

  return xhr;
}

您可以使用以下示例调用它:

jsonRequest({
  url: 'https://api.github.com/users/staxmanade/repos',
  callback: function(err, data) {
    console.log(JSON.stringify(data[0], null, ' '));
  }
});

希望这可以帮助。

于 2015-09-15T05:33:15.880 回答
2

我在 tvOS 上测试了这个 - 就像 jQuery 语法的魅力一样(基本测试通过):

var $ = {};
$.ajax = function(options) {

  var url = options.url;
  var type = options.type || 'GET';
  var headers = options.headers || {} ;
  var body = options.data || null;
  var timeout = options.timeout || null;
  var success = options.success || function(err, data) {
    console.log("options.success was missing for this request");
  };
  var contentType = options.contentType || 'application/json';
  var error = options.error || function(err, data) {
    console.log("options.error was missing for this request");
  };

  if (!url) {
    throw 'loadURL requires a url argument';
  }

  var xhr = new XMLHttpRequest();
  xhr.responseType = 'json';
  xhr.timeout = timeout;
  xhr.onreadystatechange = function() {
    try {
      if (xhr.readyState === 4) {
        if (xhr.status === 200) {
            if (xhr.responseType === 'json') {
                success(null, xhr.response);
            } else {
                success(null, JSON.parse(xhr.responseText));
            }
        } else {
          success(new Error("Error [" + xhr.status + "] making http request: " + url));
        }
      }
    } catch (err) {
      console.error('Aborting request ' + url + '. Error: ' + err);
      xhr.abort();
      error(new Error("Error making request to: " + url + " error: " + err));
    }
  };

  xhr.open(type, url, true);

  xhr.setRequestHeader("Content-Type", contentType);
  xhr.setRequestHeader("Accept", 'application/json, text/javascript, */*');

  Object.keys(headers).forEach(function(key) {
    xhr.setRequestHeader(key, headers[key]);
  });

  if(!body) {
    xhr.send();
    } else {
        xhr.send(body);
    }

  return xhr;
}

在 Apple TV 上运行的示例查询:

var testPut = function(){

    $.ajax({
        type: 'PUT',
        url: url,
        success: successFunc,
        error: errFunc,
        dataType: 'json',
        contentType: 'application/json',
        data: data2
    });
}
var testGet = function(){
    $.ajax({
        dataType: 'json',
        url: url,
        success: successFunc,
        error: errFunc,
        timeout: 2000
    });

}

var getLarge = function(){
    $.ajax({
        dataType: 'json',
        url: url,
        success: successFunc,
        error: errFunc,
        timeout: 2000
    });
}
于 2015-10-17T01:29:45.647 回答
1

我遇到了这个问题,希望完成同样的事情,并受到@JasonJerrett 回答的启发,但发现它有点缺乏,因为在我的实例中,我使用的是这样的 Javascript 内置的 XML 模板:

// Index.xml.js
var Template = function() { 
  return `very long xml string`;
};

问题是您无法在模板本身内部执行 XHR 请求,因为模板字符串将在 XHR 请求实际完成之前返回(无法从异步回调内部返回数据)。我的解决方案是在调用模板并将数据传递到模板函数之前,修改资源加载器并在那里执行 XHR 请求:

ResourceLoader.prototype.loadResource = function(resource, dataEndpoint, callback) {
    var self = this;
    evaluateScripts([resource], function(success) {
        if (success) {
            // Here's the magic. Perform the API call and once it's complete,
            // call template constructor and pass in API data
            self.getJSON(dataEndpoint, function(data) {
                var resource = Template.call(self, data);
                callback.call(self, resource);
            });
        } else {
            var title = "Failed to load resources",
                description = `There was an error attempting to load the resource. \n\n Please try again later.`,
                alert = createAlert(title, description);

            Presenter.removeLoadingIndicator();

            navigationDocument.presentModal(alert);
        }
    });
}

// From: https://mathiasbynens.be/notes/xhr-responsetype-json
ResourceLoader.prototype.getJSON = function(url, successHandler, errorHandler) {
  var xhr = new XMLHttpRequest();
  xhr.open('get', url, true);
  xhr.onreadystatechange = function() {
    var status;
    var data;
    if (xhr.readyState == 4) { 
      status = xhr.status;
      if (status == 200) {
        data = JSON.parse(xhr.responseText);
        successHandler && successHandler(data);
      } else {
        errorHandler && errorHandler(status);
      }
    }
  };
  xhr.send();
};

然后需要修改模板函数以接受传入的 API 数据作为参数:

// Index.xml.js
var Template = function(data) { 
    return 'really long xml string with injected ${data}';
};
于 2016-03-23T18:38:21.407 回答
1

您是否在“App.onLaunch”中调用了您的函数

App.onLaunch = function(options) {
  var url = 'http://query.yahooapis.com/v1/public/yql?q=select%20item%20from%20weather.forecast%20where%20location%3D%223015%22&format=json';
  var doc = getDocument(url);
  console.log(doc);
}

可能值得一看https://mathiasbynens.be/notes/xhr-responsetype-json

于 2015-09-14T17:46:38.790 回答
0

如果您想在应用启动时调用请求,只需添加 application.js:

App.onLaunch = function(options) {
  var javascriptFiles = [
    `${options.BASEURL}js/resourceLoader.js`, 
    `${options.BASEURL}js/presenter.js`
  ];

evaluateScripts(javascriptFiles, function(success) {
 if(success) {
  resourceLoader = new ResourceLoader(options.BASEURL);
  var index = resourceLoader.loadResource(`${options.BASEURL}templates/weatherTemplate.xml.js`, function(resource) {

    var doc = Presenter.makeDocument(resource);

    doc.addEventListener("select", Presenter.load.bind(Presenter));

    doc.addEventListener('load', Presenter.request);

    navigationDocument.pushDocument(doc);

  });
} else {
  var errorDoc = createAlert("Evaluate Scripts Error", "Error attempting to evaluate external JavaScript files.");
  navigationDocument.presentModal(errorDoc);
}

}); }

在presenter.js 中添加一个方法:

request: function() {

  var xmlhttp = new XMLHttpRequest() , method = 'GET' , url = 'your Api url';
  xmlhttp.open( method , url , true );
  xmlhttp.onreadystatechange = function () {
    var status;
    var data;
    if (xmlhttp.readyState == 4) {
      status = xmlhttp.status;
      if (status == 200) {
        data = JSON.parse(xmlhttp.responseText);
        console.log(data);
      } else {
        var errorDoc = createAlert("Evaluate Scripts Error", "Error attempting to evaluate external JavaScript files.");
        navigationDocument.presentModal(errorDoc);
      }
    }
  };
  xmlhttp.send();
},
于 2015-09-22T12:59:04.090 回答
0

您需要在 XHR 对象上实现onreadystatechange事件来处理响应:

templateXHR.onreadystatechange = function() {
  var status;
  var data;
  if (templateXHR.readyState == 4) { //request finished and response is ready
    status = templateXHR.status;
    if (status == 200) {
      data = JSON.parse(templateXHR.responseText);
      // pass the data to a handler
    } else {
      // handle the error
    }
  }
};
于 2015-09-14T23:11:30.077 回答