我遇到了一个奇怪的问题,我试图向开放天气历史API发出JSONP
请求,以获取特定日期前几年的天气信息。
fetchHistoryUrl = 'http://78.46.48.103/data/3.0/days?day=0622&mode=list&lat=39.77476949&lon=-100.1953125';
$.ajax({
method: 'get',
url: fetchHistoryUrl,
success: function(response){
console.log(response);
},
error : function (jqXHR, textStatus, errorThrown) {
if (typeof console == 'object' && typeof console.log == 'function') {
console.log(jqXHR);
console.log(textStatus);
console.log(errorThrown);
}
}
});
这给了我CORS问题。
所以我补充说:
dataType: 'jsonp',
但后来我收到一个错误"parsererror"
,这意味着它无法将响应解析为有效的JSON。响应代码是200 OK。
因此,如果我没有将其作为jsonp
请求,则会出现CORS问题,但如果我这样做,则会出现解析错误。我该如何解决这个问题?
修改
当我加入dataType: 'jsonp',
Object { readyState: 4, getResponseHeader: .ajax/v.getResponseHeader(), getAllResponseHeaders: .ajax/v.getAllResponseHeaders(), setRequestHeader: .ajax/v.setRequestHeader(), overrideMimeType: .ajax/v.overrideMimeType(), statusCode: .ajax/v.statusCode(), abort: .ajax/v.abort(), state: .Deferred/d.state(), always: .Deferred/d.always(), then: .Deferred/d.then(), 10 more… } jquery.min.js line 2 > eval:117:7
"parsererror" jquery.min.js line 2 > eval:118:7
Error: jQuery21102812510521974031_1434973061927 was not called
Stack trace:
.error@http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js:2:1821
b.converters["script json"]@http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js:4:16291
vc@http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js:4:7397
x@http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js:4:10802
.send/c@http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js:4:15583
n.event.dispatch@http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js:3:6352
n.event.add/r.handle@http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js:3:3162
当我不包括它时:
Object { readyState: 0, getResponseHeader: .ajax/v.getResponseHeader(), getAllResponseHeaders: .ajax/v.getAllResponseHeaders(), setRequestHeader: .ajax/v.setRequestHeader(), overrideMimeType: .ajax/v.overrideMimeType(), statusCode: .ajax/v.statusCode(), abort: .ajax/v.abort(), state: .Deferred/d.state(), always: .Deferred/d.always(), then: .Deferred/d.then(), 10 more… } jquery.min.js line 2 > eval:117:7
"error" jquery.min.js line 2 > eval:118:7
"" jquery.min.js line 2 > eval:119:7
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://78.46.48.103/data/3.0/days?day=0622&mode=list&lat=39.77476949&lon=-100.1953125. (Reason: missing token 'x-csrf-token' in CORS header 'Access-Control-Allow-Headers' from CORS preflight channel). <unknown>
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://78.46.48.103/data/3.0/days?day=0622&mode=list&lat=39.77476949&lon=-100.1953125. (Reason: CORS request failed).
答案 0 :(得分:2)
您自己提供的代码works fine。
如果您尝试强制使用JSONP,它会中断,因为您提出请求的服务器不支持JSONP。它确实支持CORS(它是JSONP的现代替代品),并且您不需要做任何特殊的事情来使用它。
您的错误:
阻止跨源请求:同源策略禁止在
http://78.46.48.103/data/3.0/days?day=0622&mode=list&lat=39.77476949&lon=-100.1953125.
读取远程资源(原因:缺少令牌&#39; x-csrf-token&#39;在CORS标头中&#39;访问 - 来自CORS预检频道的Control-Allow-Headers)。
表示如果要将其包含在跨源请求中,则需要从发出请求的站点添加需要特殊权限(可通过CORS设置)的非标准头。
它几乎可以肯定来自页面中的其他一些代码,这些代码添加了一个令牌,作为针对所有您的Ajax请求的跨站点请求伪造攻击的一般防御的一部分。
您需要限制它,以便它仅适用于您对自己网站的请求。
答案 1 :(得分:-1)
如果您遇到CORS问题,请求的服务器应授予您查询CORS。
答案 2 :(得分:-1)
JSONP已成为克服相同原始政策限制的事实上的方法,并且得到主要数据提供商(Facebook,Twitter,Google,Yahoo等)的支持。为了能够使用JSONP,第三方服务器必须支持它。换句话说,将JSON数据包装到函数调用中。
请记住,返回的数据是普通的javascript文件。这意味着您在域的范围内运行任意javascript代码,可以访问浏览器中的所有用户cookie和数据。这引入了巨大的安全问题。这就是为什么你绝对必须信任使用JSONP方法获取数据的服务器。
请参阅此link。它为跨域请求提供了进一步的解决方案。