2009-12-29 149 views
55

我想解析javscript中的bit.ly JSON响应。从XmlHttpRequest.responseJSON解析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插件中这样做。当我运行时,我得到错误“jsonResponse是未定义”的行var bitlyUrl = jsonResponse.results[url].shortUrl;。我在这里解析JSON时做错了什么?或者这个代码有什么问题?

回答

156

新方法一:fetch

TL; DR我建议这种方式,只要你不必发送同步请求或支持旧的浏览器。

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

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

兼容性:API不受IE11以及边缘12 & 13支持,但在取,有polyfills

新方法二:responseType

由于Londeren已经写在his 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); 

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

的经典方法

标准XMLHttpRequest没有responseJSON财产,只是responseTextresponseXML。正如一些JSON您的要求,只要bitly真的响应,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还提供功能来轻松地发送JavaScript对象为JSON。更多细节和代码可以在这里找到:http://pixelsvsbytes.com/2011/12/teach-your-xmlhttprequest-some-json/

完全披露:我是Pixels | Bytes的所有者。我认为我的脚本是解决问题的好办法,所以我在这里发布了它。如果您要我删除链接,请留下评论。

+1

pixelsvsbytes.com它真的值得去阅读 – CapelliC 2012-07-11 22:25:48

+3

+1;海事组织这是问题的真正答案 - 没有jQuery只是普通的旧香草'''XMLHttpRequest''';正是这个问题是关于什么的。 – 2013-01-08 01:07:38

+0

还有一个jQuery版本。如果你正在接受crossbrowser问题的尝试,通常框架可以更好地处理这些问题: http://api.jquery.com/jquery.parsejson/ – sagits 2014-01-29 17:01:01

2

我认为你必须包括jQuery使用responseJSON

没有jQuery的,你可以用responseText的尝试,并尝试像eval("("+req.responseText+")");

UPDATE:请阅读有关eval的评论,你可以评估测试,但在工作延伸不使用它。

OR

使用json_parse:它不使用eval

+4

对于铬PRIVS运行Firefox的插件,不要试图EVAL任何你从外部获取资源。相反,使用JSON.parse(至少在FF 3.5及更高版本中)。 – 2009-12-29 06:25:08

0

使用nsIJSON如果这是一个FF扩展:

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

2

注意:我只在Chrome中进行了测试。

它增加了一个原型功能了XMLHttpRequest .. XHR2

XHR 1,你可能只需要与this.responseText

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

更换this.response在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}); 
+0

如果我是你,我会定义一个[getter](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get),而不是函数属性。只需将'value'替换为传递给'Object.defineProperty'的对象中的'get',并且您可以像使用其他任何响应变量一样使用'responseJSON'。 – wizzwizz4 2016-09-16 16:35:44

4

您可以简单地设置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