跨域请求 Cross-Origin Requests

  • JSONP

定义返回函数

function callbackFun(json){
  console.log(json);
}

请求中包含 callbackFunction

<script src="http://www.example.com?q=callbackFun"><script>
$.ajax({
  url: "https://api.github.com/users/jeresig",
  dataType: "jsonp",
  jsonpCallback: "callbackFun"
});

或写成:

$.getJSON("https://api.github.com/users/jeresig?callback=?",function(json){
  console.log(json);
});

返回

callbackFun({
 "FirstName" : "xyz",
 "LastName" : "abc",
 "Grade" : "A"
 }
 );
  • CORS(Cross-Origin Resource Sharing)跨域资源共享

实现 CORS 通信的关键是服务器。只要服务器实现了 CORS 接口,就可以跨源通信。

发送请求的页面所在服务器 www.example.com 会发送

Origin: http://www.example.com

接受请求的服务器,设置 Access-Control-Allow-Origin (ACAO)header 在 response 中

Access-Control-Allow-Origin "http://www.example.com"

允许所有的域名,设置成  *

Access-Control-Allow-Origin: *

浏览器端例子:

var invocation = new XMLHttpRequest();
var url = 'http://test.com/resources/public-data/';
   
function callOtherDomain() {
  if(invocation) {    
    invocation.open('GET', url, true);
    invocation.onreadystatechange = handler;
    invocation.send(); 
  }
}
var url = 'http://test.com/cors';
var xhr = new XMLHttpRequest();
xhr.open('PUT', url, true);
xhr.setRequestHeader('X-Custom-Header', 'value');
xhr.send();

Access-Control-Allow-Credentials

该字段可选。它的值是一个布尔值,表示是否允许发送Cookie。

默认情况下,Cookie不包括在CORS请求之中。设为true,即表示服务器明确许可,Cookie可以包含在请求中,一起发给服务器。

这个值也只能设为true,如果服务器不要浏览器发送Cookie,删除该字段即可。

另一方面,开发者必须在 AJAX 请求中打开 withCredentials 属性。

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

如果要发送Cookie,Access-Control-Allow-Origin就不能设为星号,必须指定明确的、与请求网页一致的域名。

Access-Control-Expose-Headers

该字段可选。CORS请求时,XMLHttpRequest对象的getResponseHeader()方法只能拿到6个基本字段:Cache-ControlContent-LanguageContent-TypeExpiresLast-ModifiedPragma

如果想拿到其他字段,就必须在Access-Control-Expose-Headers里面指定。

  • jQuery.ajax 设置 crossDomain

crossDomain (default: false for 相同域名下的请求, true for 跨域请求)
Type: Boolean
$.ajax({
method: "POST",
url: "some.php",
data: { name: "John", location: "Boston" },
crossDomain: true
})
.done(function( msg ) {
alert( "Data Saved: " + msg );
});
  • 总结

JSONP 仅支持 GET 请求,可以在老式浏览器 IE<=9, Opera<12, or Firefox<3.5 中使用,可能产生 XSS 错误;

CORS 还支持其它的请求方式,可以使用 XMLHttpRequest ,有更好的错误处理方式,支持最新的浏览器,手动解析 response 更安全;

更多CROS,参考跨域资源共享 CORS 详解