其他分享
首页 > 其他分享> > 21.4 跨域源资源共享

21.4 跨域源资源共享

作者:互联网

由于跨域安全策略,XHR 对象只能访问与包含它的页面位于同一个域中的资源
CORS(跨域源资源共享)的基本思想就是使用自定义的 HTTP 头部让浏览器与服务器进行沟通,从而决定请求或响应是否应该成功
浏览器端在发送请求时附加一个额外的 Origin 头部,包含请求页面的来源信息
Origin:http://www.nczonline.net
服务器端,若认为请求可接受,在 Acess-Control-Allow-Origin 头部中添加相同的源信息(公共资源可以回发"*")
Access-Control-Allow-Origin:http://www.nczonline.net
若没有此回复的头部,或者头部信息不匹配,浏览器就会驳回请求

一、IE 对 CORS 的实现

引入了 XDR(XDomainRequest)类型,该类型与 XHR 有一些不同之处:
1.cookie 不会随请求发送,也不会随响应返回
2.只能设置请求头部信息中的 Content-Type 字段
3.不能访问响应头部信息
4.只支持 GRT 和 POST 请求
XDR 类型也是调用 open 和 send 方法来实现请求的发送,但是 open 方法只支持前两个参数,所有 XDR 请求都是异步执行的
XDR 响应的数据也会保存到 responseText 属性中,但是无法读取响应的状态代码,故无法确定错误原因
XDR 也可以通过 abort 方法取消请求
XDR 也有 timeout 属性和 ontimeout 事件处理程序

var xdr = new XDomainRequest(); //创建 XDR 对象
xdr.onload = function() {
    alert(xdr.responseText); //成功之后可以访问响应文本
};
xdr.onerror = function() {
    alert('an error occurred'); //无法根据状态码知晓错误原因
};
xdr.timeout = 1000;
xdr.ontimeout = function () {
    alert('request took too long'); //支持超时设置
};
xdr.open('post','http://www.somewhere.com/page/'); //URL 为绝对路径
xdr.contentType = 'application/x-www-form-urlencode'; //为 post 请求提供设置 content-type 字段的属性
xdr.send('name=value');

二、其他浏览器对 CORS 的实现

其他浏览器使用 XHR 实现 CORS,只是传入的 URL 为绝对路径,为此,本地资源请求最好使用相对路径

var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
    if(xhr.readyState === 4) {
        if((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
            console.log(xhr.responseText);
        } else {
            console.log('request was unsucessful:' + xhr.status);
        }
    }
};
xhr.open('get','http://www.somewhere.com/page/',true);
xhr.send(null);

XHR 可以访问 status 及 statusText 属性,支持同步请求,但也有一些限制
1.不能使用 setRequestHeader 设置自定义头部
2.不能发送和接收 cookie
3.调用 getAllResponseHeaders 方法总会返回空字符串

三、Preflighted Requests

CORS 在请求获取的资源之前会额外发送一次请求,用于请求服务端支持的方法、头部信息等
该请求使用 OPTIONS 方法,发送下列头部
Origin:与简单的请求相同
Access-Control-Request-Method:请求自身使用的方法
Access-Control-Request-Headers:自定义的头部信息(可选)
服务器端以同样的方式进行响应
Access-Control-Allow-Origin:与简单的请求相同
Access-Control-Allow-Methods:允许的方法
Access-Control-Allow-Headers:允许的头部
Access-Control-Max-Age: Preflight 请求缓存的时间

四、带凭据的请求

默认情况下,跨源请求不提供凭据(cookie、HTTP 认证及客户端 SSL 证明等)
通过将 withCredentials 属性设置为 true,可以指定某个请求应该发送凭据
如果服务器接受带凭据的请求,会以下面的 HTTP 头部来响应
Access-Control-Allow-Credentials: true
服务器也可以在 Preflight 请求的响应中添加该头部

五、跨浏览器的 CORS

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();
        xhr.open(method,url);
    }else {
        xhr = null;
    }
    return xhr;
}
var request = createCORSRequest('get','http://www.somewhere.com');
if(request) {
    request.onload = function() {
        //
    }
    request.send();
}
糖小昔 发布了68 篇原创文章 · 获赞 0 · 访问量 943 私信 关注

标签:资源共享,21.4,请求,Access,xhr,xdr,头部,Control,跨域
来源: https://blog.csdn.net/weixin_44774877/article/details/104143042