前端跨域解决方案

跨域源资源共享

同源:域名、端口、协议均相同
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 with padding)

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)函数

postMessage

otherWindow.postMessage(message, targetOrigin);

otherWindow:指目标窗口,也就是给哪一个window发消息,是window.frames属性的成员或者由 window.open 方法建立的窗口.
参数说明:message: 是要发送的消息,类型为 String、Object (IE八、9 不支持);targetOrigin: 是限定消息接收范围,不限制请使用*

相关文章
相关标签/搜索