各大浏览器(含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高级程序设计第三版,或者说就是作为笔记存在的
本文相关标签: 原生JS
发表评论: