这篇文章主要介绍跨域方面的知识。javascript
说跨域以前先说说同源策略,同源策略是一种约定,几乎全部现代浏览器都遵循了这种约定,它也是一种安全策略,确保非同源的请求没法随意请求,从而保证了网站的安全。同源须要保证协议,域名,端口都相同,只要有一个不一样,那么他们就不是同源的。虽然同源策略保证了安全性,但有时候咱们确实须要非同源之间相互访问,好比在先后端分离的项目中,前端和后端的地址分别为https://xwchris.me
和https://api.xwchris.me
。非同源之间跨域访问就要用到CORS跨域方法。CORS全称Cross Origin Resource Sharing
即跨域资源共享。html
如下是几种与跨域相关的头部,及简单的介绍。前端
简单请求要知足如下条件:java
GET
、HEAD
和POST
其中的一个Accept
、Accept-Language
、Content-Language
、Last-Event-ID
和Content-Type
且Content-Type
的值只限于application/x-www-form-urlencoded
、multipart/form-data
和text/plain
。浏览器发送简单请求时会自动在请求头部添加Origin
字段,表明访问源。git
要支持CORS访问须要服务器在响应头中添加Access-Control-Allow-Origin
,可使用*
来表示容许全部域跨域访问。github
非简单请求与简单请求最大的不一样在于,它有一次预请求preflight
的过程,只有此次请求校验经过,才能发送正常的请求。后端
预请求是OPTIONS
请求,浏览器会自动添加Access-Control-Allow-Headers
和Access-Control-Allow-Methods
。api
须要服务器返回的响应头包括Access-Control-Allow-Headers
、Access-Control-Allow-Methods
和Access-Control-Allow-Origin
。跨域
除了Access-Control-Allow-Origin
是必须的以外,其余两种只有在不符合简单请求须要的时候服务器才须要添加,好比在简单请求的基础上自定义了一个请求头X-xx-name: chris
,那么服务器只须要在响应头中添加Access-Control-Allow-Headers
。每种响应头均可以使用*
通配符来表示全部。浏览器
预请求完以后就能够发送正常请求了,正常请求的步骤与简单请求一致,也须要添加Access-Control-Allow-Origin
响应头。
能够经过设置Access-Control-Max-Aage
来减小预请求的次数,须要包含在预请求的响应头中,指定在该时间内预请求验证有效,没必要每次都进行预请求,它的单位是s
。如Access-Control-Max-Age: 1728000
,即有效期为20天。
默认状况下,跨域请求不会携带Cookie,若是要携带Cookie进行跨域请求须要请求方和接收方同时支持。为了支持携带Cookie须要在请求的时候由开发者手动指定请求对象xhr.withCredentials=true
。服务器响应头须要包含Access-Control-Allow-Credentials: true
,若是是非简单请求,预请求也须要包含该头部。
这里须要注意的是,在这种状况下全部须要的响应头的值都不能是*
,在须要的状况下都须要明确指定。
除了CORS,咱们还可使用JSONP
技术来进行跨域,这是一种很古老的Hack。咱们都是知道script
标签能够访问任何域下的脚本,所以能够利用这种方法来进行跨域,这须要服务器进行配合。举个栗子🌰:
<script type="text/javascript"> function getName(name) { console.log(name); } </script>
<script src="http://api.xxx.com?callback=getName"></script>
复制代码
请求服务器后服务器须要拿到callback
字段的值,而后将要返回的值变成JSON,放入getName
中。最终返回的值x像这个形式;getName({"name": "chris"})
,这样getName函数就能够就能够拿到相应的值。
JSONP相比CORS,只能进行GET请求,可是兼容性好一些。不过现代浏览器基本上都支持了CORS请求,能够放心食用。原文地址:传送门