各大浏览器(含IE8)跨域资源的实现笔记

作者: 阿蒙 时间: 2017-11-8 标签: JavaScript 浏览: 1753 评论: 0

一、 IE的XDR对CORS的支持

IE对CORS引入了 XDR(XDomainRequest )类型。 和XMLHttpRequest 对象不同的是:

   1.  cookie不会随请求发送, 也不会随相应返回

   2.  只能设置请求头部信息中的Content-Type 字段

   3.   不能访问相应头部信息

   4.   只支持GET 和 POST请求   

   5.   客户端及服务端必须使用相同的协议并且必须是http及https中的一种

   6.   截止到2014年 截至2014年,XDomainRequest 看起来好像再也不会发送任何Content-Type请求头了,也无法设置请求头了。即使是text/plain

XDR和XHR使用方法差不多 都是调用 open()之后再调用send()方法 不过XDR的open()方法只接受 请求的类型和请求的地址两个参数。

在接收到响应后,你只能访问响应的原始文本;没有办法确定响应的状态代码。而且,只要响应有效就会触发 load 事件,如果失败(包括响应中缺少 Access-Control-Allow-Origin 头部)就会触发 error 事件。遗憾的是,除了错误本身之外,没有其他信息可用,因此唯一能够确定的就只有请求未成功了 。 可以指定onerror来接受错误信息 

xdr.onerror = function(){}


更多 XDR的信息可以查看  

https://blogs.msdn.microsoft.com/ieinternals/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds/

https://developer.mozilla.org/zh-CN/docs/Web/API/XDomainRequest


二、 非IE的CORS支持

非IECORS是通过一种叫做 Preflighted Requests 的透明服务器验证机制支持开发人员使用自定义的头部、GET POST 之外的方法,以及不同类型的主体内容。在使用下列高级选项来发送请求时,就会向服务器发送一个 Preflight 请求。这种请求使用 OPTIONS 方法,发送下列头部 。

1. Origin: 与简单的请求相同

2. Access-Control-Request-Method:请求自身使用的方法
3. Access-Control-Request-Headers:(可选)自定义的头部信息,多个头部以逗号分隔

服务器根据自定义的头部信息判断该请求是否接受,再进行返回, 这种方式的代价就是需要多发一次请求。 

检测 XHR 是否支持 CORS 的最简单方式,就是检查是否存在 withCredentials 属性。再结合检测 XDomainRequest 对象是否存在,就可以兼顾所有浏览器了


function createCORSRequest(method, url) {
    var xhr = new XMLHttpRequest();
    if ("withCredentials" in xhr) {
        xhr.open(method, url, true);
    } else if (typeof XDomainRequest != "undefined") {
        vxhr = new XDomainRequest();
        xhr.open(method, url);
    } else {
        xhr = null;
    }
    return xhr;
}
var request = createCORSRequest("get", "http://www.somewhere-else.com/page/");
if (request) {
    request.onload = function() {
        //对 request.responseText 进行处理
    };
    request.send();
}


三、 带凭据的请求

默 认 情 况 下, 跨 源 请 求不 提 供 凭 据(cookie 、 HTTP 认 证 及 客户 端 SSL 证明 等 )。 通 过 将withCredentials 属性设置为 true,可以指定某个请求应该发送凭据。如果服务器接受带凭据的请求,会用下面的 HTTP 头部来响应。
Access-Control-Allow-Credentials: true
如果发送的是带凭据的请求,但服务器的响应中没有包含这个头部,那么浏览器就不会把响应交给JavaScript(于是, responseText 中将是空字符串, status 的值为 0,而且会调用 onerror()事件处理程序)。另外,服务器还可以在 Preflight 响应中发送这个 HTTP头部,表示允许源发送带凭据的请求。支持 withCredentials 属性的浏览器有 Firefox 3.5+、 Safari 4+和 Chrome。 IE 10 及更早版本都不
支持。

四、图像ping的方式

加载一张图片是不存在跨域的问题的 , 所以可以监控突破的onload时间来传递参数

var img = new Image();
img.onload = img.onerror = function(){
alert("Done!");
};
img.src = "http://www.example.com/test?name=Nicholas";
 
如上面例子就传递了一个name对象。 这种方法只支持get请求, 并且无法接收服务器返回参数。

五、JSONP 

jsonp和json差不多。 只不过是包含在回调函数中的json  如 callback({ "name": "Nicholas" });   是通过动态script标签来使用的。

缺点是  

  1. 加载其他域代码 可能不安全

  2. 请求是否失败无法确定,只能通过定时器来判断是否接收到了响应

本文是参考JavaScript高级程序设计第三版,或者说就是作为笔记存在的

0

本文相关标签: 原生JS

赞助商

发表评论: