跨域问题整理(ajax)---参考大神们的记录

ajax请求数据出现跨域的原因: 浏览器的‘同源策略’。(同源: 协议,域名,端口)

浏览器的同源策略目的:是为了保护用户信息安全,防止恶意网站窃取数据。

 

由同源策略导致限制:

1)Cookie、LocalStorage和IndexDB无法读取。

2)DOM无法获取

3)AJAX请求不能发送。

 

如何解决上述限制呢?

1)Cookie

Cookie是服务器写入浏览器的一小段信息,只有同源的网页才能共享。但是,两个网页一级域名相同,只是二级域名不同,浏览器允许通过设置document.domain共享Cookie。

LocalStorage 和 IndexDB 使用POSTMessage API。

 

2)AJAX请求

除了假设服务器代理(浏览器请求同源服务器,再由后者请求外部服务),有三种方法规避这个限制。

①JSONP

基本思想:网页通过添加一个<script>元素,向服务器请求JSON数据,这种做法不受同源政策限制;服务器收到请求后,将数据放在一个指定名字的回调函数里传回来。

function addScriptTag(src){

    var script= document.createElement('script');

    script.setAttribute('type','text/javascript');

    script.src= src;

    document.body.appendChild(script);

}

function foo(data){

   console.log('get Data '+ data);

}

window.onload = function(){

   addScriptTag('http://www.sun.com/a.html?callback=foo');

}

 

②WebSocket

WebSocket是一种通信协议,使用ws://(非加密)和wss://(加密)作为协议前缀。该协议不实行同源策略,只要服务器支持,就可以通过他进行跨源通信。

案例:

浏览器发出的WebSocket请求的头信息

GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
Origin: http://example.com

根据字段Origin,如果该域名在白名单内,服务器就会做出如下回应:

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
Sec-WebSocket-Protocol: chat

③CORS

CORS是跨域资源分享(Cross-Origin Resource Sharing)。相比JSONP只能发GET请求,CORS允许任何类型的请求。

实现cors关键在于服务器,因为基本浏览器都支持该功能并且自动完成。

浏览器将CORS请求分成两类: 简单请求和非简单请求

第一种:简单请求

只要同时满足一下两大条件,就属于简单请求:

1)请求方式: head,get,post

2)HTTP头信息不超出以下几种字段:

*Accept

*Accept-Language

*Content-Language

*Last-Event-ID

*Content-Type: 只限于三个值 application/x-www-form-urlencoded,multipart/form-data,text/plain

针对简单请求处理流程:

1)自动在头信息中添加一个Origin字段。

如果,不在许可范围内,服务器返回一个正常的HTTP响应。但是不包含Access-Control-Allow-Origin字段就显示出现。

如果,在许可范围内,服务器返回的响应会多出几个头信息字段。

Access-Control-Allow-Origin:(接受哪些域名的请求)

Access-Control-Allow-Credentials: true(是否允许在请求中发送Cookie)

Access-Control-Expose-Headers: FooBar

Content-Type: text/html;charset=utf-8

2)withCredentials属性

CORS请求默认不发送Cookie和HTTP认证信息。如果要把Cookie发送到服务器,

需设置两个地方:

①服务器同意: Access-Control-Allow-Credentials: true

② 开发者必须在AJAX请求中打开withCredentials属性。

var xhr = new XMLHttpRequest();

xhr.withCredentials =  true;

posted @ 2018-01-08 11:02  倩妞驾到  阅读(180)  评论(0编辑  收藏  举报