Cross-Origin Resource Sharing
(跨域资源共享)

前端有哪些跨域方式

简单的jsonp实现

$.getJsonp = (function () {
  var _i = 0;
  return function (url, callback) {
    var cb = '_json' + _i++;
    var head = document.getElementsByTagName('head')[0];
    var script = document.createElement('script');
    script.charset = 'utf-8';
    script.src = url + '?callback=' + cb;
    head.appendChild(script);

    window[cb] = function (json) {
      callback(json);
      head.removeChild(script);
      window[cb] = null;
    };
  };
})();

服务端的响应(PHP)

$cb = $_GET['callback'];
echo $cb . '("server's data")';

CORS是什么

Browser support

XMLHttpRequest

var xhr = new XMLHttpRequest();

//向远程主机发出HTTP请求
xhr.open('GET', 'http://other.domain/path/to/resource'); 
xhr.send();

//监控XMLHttpRequest对象的状态变化,指定回调函数
xhr.onreadystatechange = function(){
  if ( xhr.readyState == 4 && xhr.status == 200 ) {
    console.log(xhr.responseText);
  } else {
    console.log( xhr.statusText );
  }
};

默认状态下,请求不提供证书(cookie、HTTP身份验证、SSL客户端证书)。

若需要在请求中包含证书,可以设置xhr的withCredentials属性。

xhr.withCredentials = true;

但是,这些cookies仍旧遵守“同域”的准则,并不能从document.cookies或者HTTP响应头当中进行读取。

XDomainRequest

XDomainRequest简称XDR,是微软在IE8中引入的,和XMLHttpRequest类似的对象,主要就是用来发送跨域请求的。

var xdr = new XDomainRequest();

//向远程主机发出HTTP请求
xdr.open('GET', 'http://other.domain/path/to/resource'); 
xdr.send();

xdr.onload = function() {
  console.log(xdr.responseText);
};

IE9支持的还是XDomainRequest,IE10才开始引入标准的XMLHttpRequest。

跨域请求过程

预请求(preflight request)

POST请求

CORS分类

简单请求

http方法是:HEAD、GET、POST

http请求头包含:

复杂请求

简单来说,任何不满足上述简单请求要求的请求,都属于复杂请求。

与CORS相关的HTTP请求头(Request Header)

与CORS相关的HTTP响应头(Response Header)

与CORS相关的HTTP响应头(Response Header)

为跨域而配置HTTP服务器

IIS7的配置

对于IIS7来说,在站点的根目录下的web.config文件里添加如下配置:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.webServer>
    <httpProtocol>
      <customHeaders>
        <add name="Access-Control-Allow-Origin" value="*" />
      </customHeaders>
    </httpProtocol>
  </system.webServer>
</configuration> 

对于简单的跨域请求,添加Access-Control-Allow-Origin:*就行了

Apache的配置

修改apache.conf或httpd.conf配置文件的Directory, Location, Files或VirtualHost任一部分:

Header set Access-Control-Allow-Origin "*"

对于unix/linux,还可以用如下命令测试是否已正确修改

apachectl -t

Expresss.js or Node.js

对于Expresss.js, 只需
app.all('*', function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "X-Requested-With");
  next();
});
对于Node.js
https://github.com/junyiz/staticjs

enable-cors.org

http://enable-cors.org/

Thanks

/