hol*_*ard 9 api ajax jquery json http-headers
我通过ajax接收json有问题,错误如下.根据我迄今为止发现的关于错误的信息,这似乎是某种跨域问题,但我不知道这意味着什么以及如何解决它.
响应标头可能存在问题(我自己创建了API并且之前没有经验),但是如果直接在浏览器中访问URL,则会收到200 OK.
如果直接在浏览器中访问url,则会显示有效的json,因此不应该出现问题.
怎么解决这个问题?
注意:url会转到Apache服务器,而不是我已经阅读过有关该问题的Stack上95%问题的文件.
XMLHttpRequest cannot load http://localhost/api/v1/products?_=1355583847077.
Origin null is not allowed by Access-Control-Allow-Origin.
Error: error
Run Code Online (Sandbox Code Playgroud)
$.ajaxSetup ({
url: "http://localhost/api/v1/products", // <--- returns valid json if accessed in the browser
type: "GET",
dataType: "json",
cache: false,
contentType: "application/json"
})
$.ajax({
success: function(data){
console.log("You made it!");
},
error: function(xhr) {
console.log("Error: " + xhr.statusText);
}
}).done(function(data){
console.log(data);
})
Run Code Online (Sandbox Code Playgroud)
_ 1355583610778
响应标题:
Connection Keep-Alive
Content-Length 3887
Content-Type application/json
Date Sat, 15 Dec 2012 14:50:53 GMT
Keep-Alive timeout=5, max=100
Server Apache/2.2.14 (Unix) DAV/2 mod_ssl/2.2.14 OpenSSL/0.9.8l PHP/5.3.1 mod_perl/2.0.4 Perl/v5.10.1
X-Powered-By PHP/5.3.1
Run Code Online (Sandbox Code Playgroud)
请求标题:
Accept application/json, text/javascript, */*; q=0.01
Accept-Encoding gzip, deflate
Accept-Language sv-SE,sv;q=0.8,en-US;q=0.5,en;q=0.3
Connection keep-alive
Host localhost
Origin null
User-Agent Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:17.0) Gecko/17.0 Firefox/17.0
Run Code Online (Sandbox Code Playgroud)
这里没有什么...
mek*_*all 20
是的,这绝对是一个跨域问题.但不要担心,这个问题有两个解决方案.
您可以在服务器上实现对JSONP(带填充的JSON)的支持(即Fergus Morrow的解决方案).JSONP开箱即用的跨域工作,基本上是JSON填充函数调用.
在您的.ajaxSetup设置dataType中jsonp,然后在服务器端,您应该确保检查callback请求中指定的url参数.如果设置了该参数,则必须相应地填充JSON响应.
parseThis({ "json": "can", "be": "put", "in": "here" });
Run Code Online (Sandbox Code Playgroud)
以上假设callback设置为parseThis.jQuery将每默认生成的函数名,但你可以通过设置的值来覆盖这jsonpCallback在你的.ajaxSetup.
您还可以使用快捷方式通过添加?callback=?到请求URL 来告诉jQuery您正在请求JSONP .
另一种解决方案是Access-Control-Allow-Origin在响应中设置标头.
Access-Control-Allow-Origin: *
Run Code Online (Sandbox Code Playgroud)
以上将允许任何资源使用跨域服务.阅读下面链接的文章,了解有关如何配置的更多信息Access-Control-Allow.
如果您想了解有关Access-Control-Origin和CORS的更多信息,我建议您在MDN上使用本文.
我通过在服务器代码(php)中添加以下标题,以一种非常简单的方式解决了这个问题:
header('Access-Control-Allow-Origin: *');
Run Code Online (Sandbox Code Playgroud)
尝试并实现某种形式的JSONP机制.如果您正在使用PHP,它可能就像这样简单......
/* If a callback has been supplied then prepare to parse the callback
** function call back to browser along with JSON. */
$jsonp = false;
if ( isset( $_GET[ 'callback' ] ) ) {
$_GET[ 'callback' ] = strip_tags( $_GET[ 'callback' ] );
$jsonp = true;
$pre = $_GET[ 'callback' ] . '(';
$post = ');';
} //isset( $_GET[ 'callback' ] )
/* Encode JSON, and if jsonp is true, then ouput with the callback
** function; if not - just output JSON. */
$json = json_encode( /* data here */ );
print( ( $jsonp ) ? $pre . $json . $post : $json );
Run Code Online (Sandbox Code Playgroud)
所有这一切都将检查一个$_GET名为callback的var ,然后将输出包装在函数调用中 - 将$_GET['callback']名称作为函数名称.
那么你的AJAX调用会变成这样的......
$.ajax({
type: 'GET',
url: '/* script here */ ',
data: /* data here - if any */,
contentType: "jsonp", // Pay attention to the dataType/contentType
dataType: 'jsonp', // Pay attention to the dataType/contentType
success: function (json) {
/* call back */
}
});
Run Code Online (Sandbox Code Playgroud)
当jQuery 'jsonp'作为dataType/contentType给出时,它将负责为您提供回调函数名称 - 并设置回调函数等; 意思是你真的不需要做任何事情!
从jQuery文档:
"jsonp":使用JSONP加载JSON块.添加额外的"?callback =?" 到URL的末尾以指定回调.通过将查询字符串参数"_ = [TIMESTAMP]"附加到URL来禁用缓存,除非缓存选项设置为true.
结束; JSONP将是你最好的选择 - 我已经包含了PHP代码,因为你的服务器端脚本正在使用PHP; 如果没有那么原则是相同的.不管服务器端技术如何,jQuery /客户端的东西都保持不变.(一般情况下)
祝好运 :)