一步解决CORS(跨域)问题
本文最后更新于:3 年前
小张带您一步在服务器后端解决跨域问题ヾ(≧∇≦*)ゝ
CORS原理
CORS全称Cross-Origin Resource Sharing,是HTML5规范定义的如何跨域访问资源。
Origin表示本域,也就是浏览器当前页面的域。当JavaScript向外域(如sina.com)发起请求后,浏览器收到响应后,首先检查Access-Control-Allow-Origin
是否包含本域,如果是,则此次跨域请求成功,如果不是,则请求失败,JavaScript将无法获取到响应的任何数据。
假设本域是my.com
,外域是sina.com
,只要响应头Access-Control-Allow-Origin
为http://my.com
,或者是*
,本次请求就可以成功。
可见,跨域能否成功,取决于对方服务器是否愿意给你设置一个正确的Access-Control-Allow-Origin
,决定权始终在对方手中。
上面这种跨域请求,称之为“简单请求”。简单请求包括GET、HEAD和POST(POST的Content-Type类型 仅限application/x-www-form-urlencoded
、multipart/form-data
和text/plain
),并且不能出现任何自定义头(例如,X-Custom: 12345
),通常能满足90%的需求。
无论你是否需要用JavaScript通过CORS跨域请求资源,你都要了解CORS的原理。最新的浏览器全面支持HTML5。在引用外域资源时,除了JavaScript和CSS外,都要验证CORS。例如,当你引用了某个第三方CDN上的字体文件时:
1 |
|
如果该CDN服务商未正确设置Access-Control-Allow-Origin
,那么浏览器无法加载字体资源。
对于PUT、DELETE以及其他类型如application/json
的POST请求,在发送AJAX请求之前,浏览器会先发送一个OPTIONS
请求(称为preflighted请求)到这个URL上,询问目标服务器是否接受:
1 |
|
服务器必须响应并明确指出允许的Method:
1 |
|
浏览器确认服务器响应的Access-Control-Allow-Methods
头确实包含将要发送的AJAX请求的Method,才会继续发送AJAX,否则,抛出一个错误。
由于以POST
、PUT
方式传送JSON格式的数据在REST中很常见,所以要跨域正确处理POST
和PUT
请求,服务器端必须正确响应OPTIONS
请求。
一步解决跨域问题
解决方式
在项目中创建 /config/WebMvcConfig.java
并复制以下代码:
1 |
|
谁在搞事?
是它——浏览器的同源策略 。可能不好访问,所以我把大体内容摘录一下,方便大家查看学习。
1 |
|
啥时候发生?
1 |
|
换一句话说,就是 协议,端口,主机 有一个不同,就会产生跨域问题。
咋还有特例?
Internet Explorer(IE) 的同源策略有两个主要的差异点:
- 授信范围(Trust Zones):两个相互之间高度互信的域名,如公司域名(corporate domains),则不受同源策略限制。
- 端口:IE 未将端口号纳入到同源策略的检查中,因此
https://company.com:81/index.html
和https://company.com/index.html
属于同源并且不受任何限制。
这些差异点是不规范的,其它浏览器也未做出支持,但会助于开发基于window RT IE的应用程序。
吐槽:IE可不是人造革n(≧▽≦)n。
咋允许跨源访问
可以使用 CORS 来允许跨源访问。CORS 是 HTTP 的一部分,它允许服务端来指定哪些主机可以从这个服务端加载资源。
上方的代码就是使用的这个方法。
怎么区分
网站的开发者工具(F12)
报错信息举例:
msedge浏览器(新版)
chrome浏览器:
跨源网络访问
同源策略控制不同源之间的交互,例如在使用XMLHttpRequest
或 `` 标签时则会受到同源策略的约束。这些交互通常分为三类:
- 跨域写操作(Cross-origin writes)一般是被允许的。例如链接(links),重定向以及表单提交。特定少数的HTTP请求需要添加 preflight。
- 跨域资源嵌入(Cross-origin embedding)一般是被允许(后面会举例说明)。
- 跨域读操作(Cross-origin reads)一般是不被允许的,*但常可以通过内嵌资源来巧妙的进行读取访问。例如,你可以读取嵌入图片的高度和宽度,调用内嵌脚本的方法。
参考:
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!