关于跨域

首先啥叫跨域,只要域名,端口,协议,二级域名有一个不一样的就叫跨域。最直观的例子就是script/img标签的src,不过这种跨域只能在HTML中,浏览器出于安全考虑会禁止js脚本的跨站请求。

为了开发更加强大的web应用,充满智慧的程序员们创造出了了很多方法,比如jsonp、cors和postMessage。 用哪种方法好哪,我们希望这种方法应该尽量强大,而且不要太复杂。所以我选择了CORS(HTTP访问控制)。jsonp是由script的src进行了一些封装,所以他只能使用GET方法,不过它支持IE6。postMessage是HTML5 新增的API,浏览器对cors和postMessage的兼容都达到了IE8+,但是CORS更加简单一些。

使用CORS能有多简单哪,只要我们在服务端的HTTP响应头加入以下

Access-Control-Allow-Origin: http://foo.example   //指定一个允许向该服务器提交请求的URI,指定为'*'表示允许所有域
Access-Control-Allow-Methods: POST, GET, OPTIONS  //设置允许的HTTP方法
Access-Control-Allow-Headers: X-PINGOTHER         //设置浏览器允许访问的服务器的头信息的白名单
Access-Control-Max-Age: 1728000                   //设置预请求的结果的有效期

服务端配置(Express Nodejs)

app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
  next();
});

在其他服务器上的配置可以看这里:I want to add CORS support to my server

浏览器对CORS的实现 Webkit内核的浏览器通过XMLHttpRequest对象实现了对CORS的原生支持,IE使用XDR类型,需要注意XDR与XHR的区别

  • cookie不会随请求发送,也不会随请求返回
  • 只能设置请求头部信息中的Content-Type字段
  • 不能访问响应头部信息
  • 只支持GET和POST

示例代码:

var createCORSRequest = function(method, url) {
  var xhr = new XMLHttpRequest();
  if ("withCredentials" in xhr) {
    // Most browsers.
    xhr.open(method, url, true);
  } else if (typeof XDomainRequest != "undefined") {
    // IE8 & IE9
    xhr = new XDomainRequest();
    xhr.open(method, url);
  } else {
    // CORS not supported.
    xhr = null;
  }
  return xhr;
};

var url = '1243';
var method = 'POST';
var xhr = createCORSRequest(method, url);

xhr.onload = function() {
  // Success code goes here.
};

xhr.onerror = function() {
  // Error code goes here.
};

xhr.withCredentials = true; //使得Cookies可以随着请求发送
xhr.open('GET',url,true) //传入绝对URL
xhr.send();

从CORS的工作原理可以看出它是基于HTTP的,所以这也带来了一定的安全问题,所以还要用OAuth来解决。

扩展阅读: HTTP访问控制(CORS) enable cross-origin resource sharing test-cors 理解OAuth 2.0

Licensed under CC BY-NC-SA 4.0