JavaScript 中的跨域请求与 jQuery 的 JSONP



我试图通过以下模板从客户端(浏览器)用JavaScript编写跨域请求(例如,Google Finance资源):

function createCORSRequest(method, url) {
  var xhr = new XMLHttpRequest();
  if ("withCredentials" in xhr) {
    xhr.open(method, url, true);    
  } else if (typeof XDomainRequest != "undefined") {
    xhr = new XDomainRequest();
    xhr.open(method, url);    
  } else {    
    // Otherwise, CORS is not supported by the browser.
    xhr = null;    
  }
  return xhr;
}
var url = 'http://finance.google.com/finance/info?client=ig&q=NASDAQ:GOOGL';
var xhr = createCORSRequest('GET', url);
if (!xhr) {
  throw new Error('CORS not supported');
}
// Response handlers.
xhr.onload = function() {
    var text = xhr.responseText;
    var jsonReturend = JSON.parse(text);
    console.log(jsonReturend)
};
xhr.onerror = function() {
    alert('Woops, there was an error making the request.');
};
xhr.send();

但它不起作用,因为(我认为)"financiancegoogle.com"的响应头中没有包含Access-Control-Allow-Origin:,这是可以理解的。然而,我在StackOverflow帖子上尝试了另一种建议的方法,使用JSONP如下:

$.ajax({
    url: 'http://finance.google.com/finance/info?client=ig&q=NASDAQ:GOOGL', 
    jsonp: "callback",
    dataType: "jsonp", 
    data: {},
    // Work with the response
    success: function( response ) {
        console.log( response ); // server response
    }
});

,它工作了(也就是说,我得到了预期的JSON)!作为web开发和JS的新手,我不确定为什么AJAX调用通过jQuery的JSONP工作,而它在纯JavaScript失败。我的问题是:

  1. JSONP做了什么不同的事情使事情工作?或者仅仅是因为' financie.google.com '允许JSONP类型的请求(但是不是CORS类型的请求)?
  2. 是否有可能通过严格使用JavaScript使其工作?如果是这样,我怎么才能做到呢?

谢谢大家的回答!

服务器必须允许使用Access-Control-Allow-Origin的跨域XHR请求。JSONP是一种绕过它的机制。

这个wiki页面包含了它为什么工作的很好的描述。参见Script元素注入部分。

https://en.wikipedia.org/wiki/JSONP

这个stackoverflow答案展示了如何使用纯javascript进行jsonp调用。

有人能解释一下JSONP是什么吗?

首先,我将在这里显示请求的响应:

// [ { "id": "694653" ,"t" : "GOOGL" ,"e" : "NASDAQ" ,"l" : "796.87" ,"l_fix" : "796.87" ,"l_cur" : "796.87" ,"s": "2" ,"ltt":"4:00PM EDT" ,"lt" : "Sep 2, 4:00PM EDT" ,"lt_dts" : "2016-09-02T16:00:02Z" ,"c" : "+5.47" ,"c_fix" : "5.47" ,"cp" : "0.69" ,"cp_fix" : "0.69" ,"ccol" : "chg" ,"pcls_fix" : "791.4" ,"el": "796.01" ,"el_fix": "796.01" ,"el_cur": "796.01" ,"elt" : "Sep 2, 7:45PM EDT" ,"ec" : "-0.86" ,"ec_fix" : "-0.86" ,"ecp" : "-0.11" ,"ecp_fix" : "-0.11" ,"eccol" : "chr" ,"div" : "" ,"yld" : "" } ] 

实际上,javascript模板中的XHR请求是有效的。错误发生时,脚本试图解析JSON文本(var jsonReturend = JSON.parse(text);)。这是因为你要解析的文本不是一个好的json文本。您可以看到上面的响应,它在开头有两个斜杠。JSON不应该有它。
因此,要使JSON.parse()可解析文本,您需要删除这些斜杠。这是你的javascript块的修复:

// Response handlers.
xhr.onload = function() {
    var text = xhr.responseText;
    text    = text.replace("// ","");// replace slashes, make it a pure JSON text
    var jsonReturend = JSON.parse(text);
    console.log(jsonReturend)
};

现在,JSON.parse()将能够解析文本。JSONP在jquery ajax请求中只是一个格式化请求响应的选项。它与请求本身无关。如果将ajax选项设置为dataType:"jsonp",则脚本将正常工作。如果将其设置为dataType:"json",则脚本将不起作用。dataType选项定义了响应的格式。
当然,您也可以使用dataType:"text"。但是不能直接作为object或JSON使用

相关内容

  • 没有找到相关文章

最新更新