【问题标题】:Parsing JSON from XmlHttpRequest.responseJSON从 XmlHttpRequest.responseJSON 解析 JSON
【发布时间】:2010-12-30 16:43:42
【问题描述】:

我正在尝试在 javascript 中解析一个 bit.ly JSON 响应。

我通过 XmlHttpRequest 获取 JSON。

var req = new XMLHttpRequest;  
req.overrideMimeType("application/json");  
req.open('GET', BITLY_CREATE_API + encodeURIComponent(url)
          + BITLY_API_LOGIN, true);  
var target = this;  
req.onload  = function() {target.parseJSON(req, url)};  
req.send(null);

parseJSON: function(req, url) {  
if (req.status == 200) {  
    var jsonResponse = req.responseJSON;  
    var bitlyUrl = jsonResponse.results[url].shortUrl;  
}

我在 Firefox 插件中执行此操作。当我运行时,var bitlyUrl = jsonResponse.results[url].shortUrl; 行出现错误“jsonResponse 未定义”。我在这里解析 JSON 有什么问题吗?或者这段代码有什么问题?

【问题讨论】:

    标签: javascript json firefox-addon bit.ly


    【解决方案1】:

    我的新方法:fetch

    TL;DR只要您不必发送同步请求或支持旧浏览器,我会推荐这种方式。

    只要您的请求是异步的,您就可以使用Fetch API 发送HTTP 请求。 fetch API 与 promises 一起使用,这是在 JavaScript 中处理异步工作流的好方法。使用这种方法,您使用fetch() 发送请求并使用ResponseBody.json() 解析响应:

    fetch(url)
      .then(function(response) {
        return response.json();
      })
      .then(function(jsonResponse) {
        // do something with jsonResponse
      });
    

    兼容性:IE11 以及 Edge 12 和 13 不支持 Fetch API。但是,有 polyfills

    新方法二:responseType

    正如Londerenhis answer 中所写,较新的浏览器允许您使用responseType 属性来定义响应的预期格式。然后可以通过response 属性访问解析的响应数据:

    var req = new XMLHttpRequest();
    req.responseType = 'json';
    req.open('GET', url, true);
    req.onload  = function() {
       var jsonResponse = req.response;
       // do something with jsonResponse
    };
    req.send(null);
    

    兼容性:IE11 不支持responseType = 'json'

    经典方式

    标准的 XMLHttpRequest 没有responseJSON 属性,只有responseTextresponseXML。只要 bitly 真的用一些 JSON 响应您的请求,responseText 应该包含 JSON 代码作为文本,所以您所要做的就是用 JSON.parse() 解析它:

    var req = new XMLHttpRequest();
    req.overrideMimeType("application/json");
    req.open('GET', url, true);
    req.onload  = function() {
       var jsonResponse = JSON.parse(req.responseText);
       // do something with jsonResponse
    };
    req.send(null);
    

    兼容性:这种方法应该适用于任何支持XMLHttpRequestJSON 的浏览器。

    JSONHttpRequest

    如果您更喜欢使用responseJSON,但想要一个比 JQuery 更轻量级的解决方案,您可能需要查看我的 JSONHttpRequest。它的工作方式与普通 XMLHttpRequest 完全相同,但还提供了responseJSON 属性。您只需更改代码中的第一行即可:

    var req = new JSONHttpRequest();
    

    JSONHttpRequest 还提供了以 JSON 格式轻松发送 JavaScript 对象的功能。更多细节和代码可以在这里找到:http://pixelsvsbytes.com/2011/12/teach-your-xmlhttprequest-some-json/

    完全披露:我是 Pixels|Bytes 的所有者。我认为我的脚本是原始问题的一个很好的解决方案,但今天它已经过时了。我不建议再使用它了。

    【讨论】:

    • +1; IMO 这是问题的真正答案 - 没有 jQuery 只是普通的旧香草 XMLHttpRequest;问题是关于什么的。
    • 那里s a jquery version too. If you are getting crossbrowser issues 试试看,通常框架更好地处理这些问题:api.jquery.com/jquery.parsejson
    • 四年后,这仍然在帮助人们。 :) 链接到博客很好 IMO,因为它确实是对示例代码和下载问题的完整答案。谢谢!
    • “使用新库”并没有想象中那么有用。
    • @GrunionShaftoe 你能解释一下,是什么意思吗?我不建议使用新库。我推荐的解决方案fetch 是标准 JavaScript。
    【解决方案2】:

    你可以简单地设置xhr.responseType = 'json';

    const xhr = new XMLHttpRequest();
    xhr.open('GET', 'https://jsonplaceholder.typicode.com/posts/1');
    xhr.responseType = 'json';
    xhr.onload = function(e) {
      if (this.status == 200) {
        console.log('response', this.response); // JSON response  
      }
    };
    xhr.send();
      

    Documentation for responseType

    【讨论】:

    • 这里有一个主要警告:IE 和当前版本的 Edge 都不支持这一点(也许 Edge 最终会在过渡到 Chromium 之后)
    【解决方案3】:

    注意:我只在 Chrome 中测试过。

    它在 XMLHttpRequest 中添加了一个原型函数 .. XHR2,

    XHR 1 中,您可能只需要将 this.response 替换为 this.responseText

    Object.defineProperty(XMLHttpRequest.prototype,'responseJSON',{value:function(){
     return JSON.parse(this.response);
    },writable:false,enumerable:false});
    

    返回 xhr2 中的 json

    xhr.onload=function(){
     console.log(this.responseJSON());
    }
    

    编辑

    如果您打算将 XHR 与 arraybuffer 或其他响应类型一起使用,那么您必须检查响应是否为 string

    在任何情况下,您都必须添加更多检查,例如如果它无法解析 json。

    Object.defineProperty(XMLHttpRequest.prototype,'responseJSON',{value:function(){
     return (typeof this.response==='string'?JSON.parse(this.response):this.response);
    },writable:false,enumerable:false});
    

    【讨论】:

    • 如果我是你,我会定义一个 getter 而不是函数属性。只需将传递给Object.defineProperty 的对象中的value 替换为get,您就可以像使用任何其他响应变量一样使用responseJSON
    【解决方案4】:

    我认为你必须包含 jQuery 才能使用responseJSON

    如果没有 jQuery,您可以尝试使用 responseText 并尝试像 eval("("+req.responseText+")");

    更新:请阅读关于eval的评论,你可以用eval测试,但不要在工作扩展中使用它。

    使用json_parse:不使用eval

    【讨论】:

    • 对于使用 chrome privs 运行的 Firefox 插件,不要尝试评估从外部来源获得的任何内容。而是使用 JSON.parse(至少在 FF 3.5 及更高版本中)。
    【解决方案5】:

    如果用于 FF 扩展,请使用 nsIJSON

    var req = new XMLHttpRequest;
    req.overrideMimeType("application/json");
    req.open('GET', BITLY_CREATE_API + encodeURIComponent(url) + BITLY_API_LOGIN, true);
    var target = this;
    req.onload = function() {target.parseJSON(req, url)};
    req.send(null);
    
    parseJSON: function(req, url) {
    if (req.status == 200) {
      var jsonResponse = Components.classes["@mozilla.org/dom/json;1"]
          .createInstance(Components.interfaces.nsIJSON.decode(req.responseText);
      var bitlyUrl = jsonResponse.results[url].shortUrl;
    }
    

    对于网页,只需使用JSON.parse 而不是Components.classes["@mozilla.org/dom/json;1"].createInstance(Components.interfaces.nsIJSON.decode

    【讨论】:

      猜你喜欢
      • 2012-10-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-28
      相关资源
      最近更新 更多