同源:域名、端口、协议均相同
CORS基本思想是使用自定义的HTTP头部,让服务器能声明容许访问的来源。
使用CORS时,异步请求会被分为简单请求(非Preflight)和非简单请求。javascript
全部的跨域请求(简单或非简单)总会包含一个origin的请求头部,由浏览器添加不受用户控制。值由协议、域名、端口组成,说明请求的来源。下面为一个Origin头部示例:java
Origin:http://www.hello.com
服务器接受这个请求,会在响应头Access-Control-Allow-Origin
回发相同的源信息。( * 代表该资源能够被任意外域访问)跨域
Access-Control-Allow-Origin:http://www.hello.com
非简单CORS请求会在正式请求以前发送一次Preflight
请求,获得确认以后才会发送真正的XMLHttpRequest请求。浏览器自动处理这两个请求,而且Preflight请求结束后,结果将按照响应中指定的时间缓存起来.因此只是第一次发送这种请求时会多一次HTTP请求. Preflight
请求使用OPTIONS方法,发送下列头部:浏览器
Origin:与简单请求相同 Access-Control-Request-Method:请求自身使用的方法
如下是一个带有自定义头部Custom-Header
的使用POST方法发送的请求.缓存
Origin:http://www.hello.com Access-Control-Request-Method:POST Access-Control-Request-Headers:Custom-Header
var url = 'http://www.hello.com'; var xhr = new XMLHttpRequest(); xhr.open('POST', url, true); xhr.setRequestHeader('Custom-Header', 'value'); xhr.send();
服务器经过在响应中发送以下头部与浏览器沟通:bash
Access-Control-Allow-Origin:http://www.hello.com Access-Control-Allow-Methods:POST,GET Access-Control-Allow-Headers:Custom-Header Access-Control-Allow-Max-Age:28000 //表示将Preflight缓存的时长(秒),期间内无需再次发送预请求
另外经过将XMLHttpRequest的withCredentials属性设置为true就能够发送带凭据(cookie、HTTP认证、客户端SSL证实等)的跨域请求.服务器
var xhr=new XMLHttpRequest(); xhr.withCredentials=true;
若是服务器接受带凭据的请求会用下面的HTTP头部响应:cookie
Access-Control-Allow-Credentials:true
JSONP由两部分组成:回调函数+数据,回调函数是当响应到来时应该在页面中调用的函数,回调函数的名字通常是在请求中指定的.而数据就是传入回调函数中的JSON数据.JSONP是经过动态<script>
元素,为其src属性指定一个跨域的URL.异步
function doSomething(response) { console.log(response); } var script=document.createElement('script'); script.src='http://www.hello.com?callback=doSomething'; document.body.insertBefore(script,document.body.firstChild);
1.定义方法doSomething,而后把doSomething传给服务器,告知服务器我须要调用doSomething方法.
2.服务端生成JSON.将JSON数据以参数的形式放到doSomething中,这样就生成了一段js脚本返回给客户端.
3.客户端浏览器解析script标签,执行doSomething(JSON)函数
otherWindow.postMessage(message, targetOrigin);
otherWindow:指目标窗口,也就是给哪一个window发消息,是window.frames属性的成员或者由 window.open 方法建立的窗口.
参数说明:message: 是要发送的消息,类型为 String、Object (IE八、9 不支持);targetOrigin: 是限定消息接收范围,不限制请使用*