同源策略规定,AJAX 请求(XMLHttpRequest
)只能发给同源的网址,不然就会出错。所谓的同源策略是指 3 个相同:协议相同、域名相同、端口相同。html
好比 http://www.example.com/index.html
这个网址,协议是http
,域名是 www.example.com
,端口是默认的 80
。若是你在这个网站上使用 AJAX 发送 http://www.example1.com/index.html
请求,就会出错,由于域名不一样。前端
AJAX 跨域的根本缘由是浏览器不容许这么作(不是服务端的问题),浏览器限制 AJAX 跨域请求的目的是为了保证用户信息的安全,防止数据被恶意获取。jquery
2.1 JSONP 如何解决跨域问题git
<img src="">
与 <script src="">
标签<script>
一样的方式发送请求,把返回的 JSON 数据封装,而后以 JS 脚本形式返回callback
参数请求跨域服务端,服务端返回数据时用 callback
参数名做为返回的函数名来包裹住返回的 JSON 数据2.2 JSONP 示例github
这里咱们以 MOOC 网为例,当访问 https://www.imooc.com/
时,会发送一个 https://www.imooc.com/index/getstarlist
AJAX 请求,下面是访问后返回的 JSON 数据。spring
咱们以 JONP 的形式(https://www.imooc.com/index/getstarlist?callback=test
)访问。json
2.3 JSONP 的弊端后端
AbstractJsonpResponseBodyAdvice
切面,不过如今这个类已通过时了,也就是说如今不推荐使用 JSONP 来解决跨域问题GET
方式的请求XMLHttpRequest
请求(script
),因此不支持异步事件等,不过这也是为何 JSONP 能够解决跨域问题的缘由CORS 跨资源共享(Cross-origin resource sharing)是一种机制,它经过添加 HTTP 头信息,解决 AJAX 跨域资源访问问题。跨域
CORS 请求能够分为两类:简单请求与非简单请求,主要区别是非简单请求在进行访问以前,会发送一个预检请求。“预检”请求首先经过 OPTIONS 方法向另外一域上的资源发送HTTP请求,以便肯定实际请求是否安全发送。为了防止每次非简单请求以前都发送预检请求,能够在服务端设置预检请求的缓存的时间。浏览器
3.1 简单请求
HEAD
、GET
、POST
中的 1 种header
中没有自定义的请求头Content-Type
为如下几种:application/x-www-form-urlencoded
、multipart/form-data
、text/plain
3.2 非简单请求
header
中包含自定义请求头 的 AJAX 请求PUT
、DELETE
形式的 AJAX 请求Content-Type
字段的类型是 application/json
等我本身在本地写了一个测试跨域的 demo(Spring Boot),经过端口 8082 发出请求(携带自定义的请求头)访问端口为 8081 的服务。下面是 Chrome 控制台有关 HTTP 的控制信息。
经过上面的图能够看出 CORS 解决跨域问题的关键所在,添加必要的请求头与响应头信息,下面是有关的头信息介绍。
3.3 HTTP 响应首部字段
Access-Control-Allow-Origin
:指定了容许访问该资源的外域 URI。对于不须要携带身份凭证的请求,服务器能够指定该字段的值为通配符,表示容许来自全部域的请求。Access-Control-Allow-Methods
:指明了实际请求所容许使用的 HTTP 方法Access-Control-Expose-Headers
:在跨域访问时,XMLHttpRequest
对象的getResponseHeader()
方法只能拿到一些最基本的响应头,若是要携带自定义的请求头,须要在该首部中进行容许的请求头放入白名单Access-Control-Max-Age
:非简单请求预检命令的最大缓存时间,在缓存时间内,对于非简单请求,不会再发送预检请求Access-Control-Allow-Credentials
:是否容许携带身份凭证(Cookie)的请求3.4 HTTP 请求首部字段
Origin
:代表预检请求或实际请求的源 URLAccess-Control-Request-Method
:用于预检请求。其做用是,将实际请求所使用的 HTTP 方法告诉服务器Access-Control-Request-Headers
:用于预检请求。其做用是,将实际请求所携带的首部字段告诉服务器能解决跨域的方式还有不少,好比禁止浏览器的跨域、Nginx 解决跨域等。这里只讲解了两种常见的跨域方式,由于 JSONP 存在一些弊端,所以推荐使用 CORS 等方式来解决跨域问题。
跨域问题,涉及到不少有关 HTTP 协议 的知识,但愿你们重视计算机基础知识。上面那个测试的 demo 上传到了 GitHub,demo 是用 Spring Boot 实现的,有须要的能够点我前往~
跨域资源共享 CORS 详解l
【原创】说说JSON和JSONP,也许你会豁然开朗,含jQuery用例
Cross-Origin Resource Sharing (CORS)