发布自 Kindem的博客,欢迎你们转载,可是要注意注明出处。另外,该文章收纳在 Kindem的我的的 IT 知识整理仓库,欢迎 Star、Fork、投稿
所谓Ajax跨域
指的是Ajax
请求从其余的域获取数据或者传输数据html
所谓域同源,指的是两个服务器资源的根url
的域名
、端口
、协议
三者彻底相同,只要三者中任何一个不一样,则说明产生了跨域前端
给一个例子,对于第一个服务器资源,其余一些url
的同源状况以下:java
http://www.test.com/index.html http://www.test.com/index.js 同源 http://www.test.com/login/login.js 同源 https://www.test.com/index.html 跨域(协议) http://www.a.com/index.html 跨域(域名) http://a.com/index.html 跨域(不一样子域) http://www.test.com:8080/index.html 跨域(端口)
CORS
是一个W3C
标准,其全称为Cross-Origin Resource Sharing
,即跨域资源共享。它容许浏览器向跨域服务器发送XMLHttpRequest
请求,从而克服了Ajax
只能同源使用的限制git
CORS
须要浏览器和服务器同时支持,目前主流浏览器都支持这个标准(IE
>=10),因此CORS
的关键主要在于服务器,要支持这个功能,每每开发者须要在服务器端进行额外设置github
另外,CORS
标准对用户来讲是透明的,用户感知不到CORS
的存在,一切都是浏览器自动完成。当浏览器检测到跨域的Ajax
请求时,就会自动作出一些处理,使得请求可以跨域ajax
跨域的Ajax
请求分为两种:json
简单请求:跨域
HEAD
、POST
、GET
之一HTTP
头字段只有Accept
、Accept-Language
、Content-Language
、Last-Event-ID
、Content-Type
中的一种或多种HTTP
头字段中的Content-Type
字段的取值为application/x-www-form-urlencoded
、multipart/form-data
、text/plain
之一CORS
对于两种不一样的请求的处理是不一样的浏览器
对于简单请求,一个跨域Ajax
请求的处理流程以下:
HTTP
头中添加Origin
字段,表示此次请求来自的域服务器根据Origin
字段判断这一次请求是否在许可范围内:
HTTP
响应,只不过响应的HTTP
头中没有Access-Control-Allow-Origin
字段,浏览器将认为这一次跨域Ajax
没能成功若是在,服务器会在响应HTTP
头中添加这几个字段
Access-Control-Allow-Origin
: 这个字段标识服务器认同的Origin
,这个Origin
为*
时标识服务器认同全部源。只有请求的HTTP
头的Origin
与该字段同源时,浏览器才会认为这一次跨域Ajax
请求成功了Access-Control-Allow-Credentials
: 这个字段标识服务器容许Cookie
,若是设置为true
则标识容许,默认为不容许Access-Control-Expose-Headers
: 容许XMLHttpRequest
获取的额外字段名对于非简单请求,一个跨域Ajax
请求的处理流程以下:
浏览器在发送正式的Ajax
请求以前,会提早发送一次OPTIONS
请求,头信息中有:
Origin
: 请求的源Access-Control-Request-Method
: 浏览器会用的的HTTP
方法Access-Control-Request-Headers
: 浏览器会额外发送的头信息字段Access-Control-Allow-Origin
HTTP
响应,则浏览器会认为OPTIONS
请求成功,接下来则会进行真正的的请求HTTP
响应中也带上Access-Control-Allow-Origin
,浏览器会再一次校验这一字段可见CORS
标准自己并不复杂,其核心是服务器和浏览器验证域是否被容许
JSONP
的全称为JSON with Padding
,是JSON
数据的一种使用模式,JSONP
一样是为了支持跨域Ajax
请求而生的,可是它相对CORS
来讲对古老的浏览器兼容性较好,也更加简单。
JSONP
的原理是JavaScript
注入,在html
中使用<script>
标签引入JavaScript
脚本是不会受到同源限制的,这意味着能够经过<script>
标签引入来自跨域的脚本,像这样:
// origin: http://www.test.com <script> function dealData(jsonData) { // do something with jsonData } </script> <script src="http://www.a.com/data.js"></script>
想象一下若是引入的脚本是这样的:
dealData({ username: 'kindem', age: 15, // ... });
不是就至关于从服务器拿到一段数据而且进行处理了吗?
接下来能够设想一下,假设服务器对于src
指向的url
的处理并非返回一个静态文件,而是动态地组合出一段文本,这段文本一上面给的形式返回,里面的参数由服务器动态生成,而调用的函数则是前端约定好的函数,则至关于变相地返回了一段跨域的数据,这就是JSONP
的核心思想