跨域就这么点事儿

这篇文章主要介绍跨域方面的知识。javascript

说跨域以前先说说同源策略,同源策略是一种约定,几乎全部现代浏览器都遵循了这种约定,它也是一种安全策略,确保非同源的请求没法随意请求,从而保证了网站的安全。同源须要保证协议,域名,端口都相同,只要有一个不一样,那么他们就不是同源的。虽然同源策略保证了安全性,但有时候咱们确实须要非同源之间相互访问,好比在先后端分离的项目中,前端和后端的地址分别为https://xwchris.mehttps://api.xwchris.me。非同源之间跨域访问就要用到CORS跨域方法。CORS全称Cross Origin Resource Sharing即跨域资源共享。html

CORS跨域相关头部

如下是几种与跨域相关的头部,及简单的介绍。前端

  • Access-Control-Allow-Headers(请求头,响应头,预请求)(携带Cookie状况下不能为*)
  • Access-Control-Allow-Methods(请求头,响应头,预请求)(携带Cookie状况下不能为*)
  • Access-Control-Allow-Origin(响应头,预请求/正常请求)(携带Cookie状况下不能为*)
  • Access-Control-Allow-Credentials(响应头,预请求/正常请求)(携带Cookie状况下要设置为true)
  • Access-Control-Max-Age(响应头,预请求)(单位s)

简单请求的CORS

简单请求要知足如下条件:java

  1. 请求方法必须是GETHEADPOST其中的一个
  2. HTTP信息不能超过如下几种字段AcceptAccept-LanguageContent-LanguageLast-Event-IDContent-TypeContent-Type的值只限于application/x-www-form-urlencodedmultipart/form-datatext/plain

浏览器发送简单请求时会自动在请求头部添加Origin字段,表明访问源。git

要支持CORS访问须要服务器在响应头中添加Access-Control-Allow-Origin,可使用*来表示容许全部域跨域访问。github

非简单请求的CORS

非简单请求与简单请求最大的不一样在于,它有一次预请求preflight的过程,只有此次请求校验经过,才能发送正常的请求。后端

预请求

预请求是OPTIONS请求,浏览器会自动添加Access-Control-Allow-HeadersAccess-Control-Allow-Methodsapi

须要服务器返回的响应头包括Access-Control-Allow-HeadersAccess-Control-Allow-MethodsAccess-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进行跨域请求须要请求方和接收方同时支持。为了支持携带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请求,能够放心食用。原文地址:传送门

相关文章
相关标签/搜索