Access-Control-Allow-Origin 跨域问题 SpringMVC解决 与 前端JS Webpack解决
跨域:浏览器对于JS的同源策略的限制。
以下情况都属于跨域:
域名不同 如: www.jd.com www.taobao.com
域名相同,端口不同 如: www.taobao.com:8081 www.taobao.com:8082
二级域名不同 如: 3c.tmall.com chaoshi.tmall.com
http和https也属于跨域
-
Jsonp
最早的解决方案,利用script标签可以跨域的原理实现。 限制:需要服务的支持 ; 只能发起GET请求
-
nginx反向代理
思路是:利用nginx把跨域反向代理为不跨域,支持各种请求方式 缺点:需要在nginx进行额外配置,语义不清晰
-
CORS
规范化的跨域请求解决方案,安全可靠。
优势:在服务端进行控制是否允许跨域,可自定义规则 ; 支持各种请求方式
缺点: 会产生额外的请求
*****因为我们将采用CORS的方式解决,故重点介绍一下它如何来处理!!!*****
它允许浏览器向跨源服务器,发出XMLHttpRequest
请求,从而克服了AJAX只能同源使用的限制。
CORS需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。
-
浏览器端:目前,所有浏览器都支持该功能(IE10以下不行)。整个CORS通信过程,都是浏览器自动完成,不需要用户参与。
-
服务端:CORS通信与AJAX没有任何差别,因此你不需要改变以前的业务逻辑。浏览器会在请求中携带一些头信息,我们需要以此判断是否允许其跨域,然后在响应头中加入一些信息即可。这一般通过过滤器完成即可。
浏览器会将ajax请求分为两类,其处理方案略有差异:简单请求、特殊请求
只要同时满足以下两大条件,就属于简单请求。:
(1) 请求方法是以下三种方法之一:HEAD GET POST
(2)HTTP的头信息不超出以下几种字段: Accept Accept-Language Content-Language Last-Event-ID Content-Type:只限于三个值application/x-www-form-urlencoded
、multipart/form-data
、text/plain
当浏览器发现发起的ajax请求是简单请求时,会在请求头中携带一个字段:Origin
如果服务器允许跨域,需要在返回的响应头中携带下面信息:
Access-Control-Allow-Origin: http://yangw.com
Access-Control-Allow-Credentials: true
Content-Type: text/html; charset=utf-8
Access-Control-Allow-Credentials:是否允许携带cookie,默认情况下,cors不会携带cookie,除非这个值是true
要想操作cookie,需要满足3个条件:
服务的响应头中需要携带Access-Control-Allow-Credentials并且为true。
浏览器发起ajax需要指定withCredentials 为true
响应头中的Access-Control-Allow-Origin一定不能为*,必须是指定的域名
不符合简单请求的条件,会被浏览器判定为特殊请求,,例如请求方式为PUT。
特殊请求会在正式通信之前,增加一次HTTP查询请求,称为"预检"请求(preflight)。
浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段。只有得到肯定答复,浏览器才会发出正式的XMLHttpRequest
请求,否则就报错。
与简单请求相比,除了Origin以外,多了两个头:
Access-Control-Request-Method: 接下来会用到的请求方式,比如PUT
Access-Control-Request-Headers: 会额外用到的头信息
Access-Control-Max-Age:本次许可的有效时长,单位是秒,过期之前的ajax请求就无需再次进行预检了(让它默认,不用处理)
我们只要解决了复杂清醒,简单情形自然包含了!
解决方式1:后端JAVA
我们用Java框架SpringMVC实现: 由于我这里是一个Spring Cloud项目,故写了个过滤器放在了网关里面统一处理
解决方式2--只在前端webpack-dev-server:
webpack配置中主要的参数说明
2.1 ‘/api’
捕获API的标志,如果API中有这个字符串,那么就开始匹配代理,
比如API请求/api/users, 会被代理到请求 http://www.baidu.com/api/users 。
2.2 target
代理的API地址,就是需要跨域的API地址。
地址可以是域名,如:http://www.baidu.com
也可以是IP地址:http://127.0.0.1:3000
如果是域名需要额外添加一个参数changeOrigin: true,否则会代理失败。
2.3 pathRewrite
路径重写,也就是说会修改最终请求的API路径。
比如访问的API路径:/api/users,
设置pathRewrite: {’^/api’ : ‘’},后,
最终代理访问的路径:http://www.baidu.com/users,
这个参数的目的是给代理命名后,在访问时把命名删除掉。
2.4 changeOrigin
这个参数可以让target参数是域名。
2.5 secure
secure: false,不检查安全问题。
设置后,可以接受运行在 HTTPS 上,可以使用无效证书的后端服务器
2.6 其他参数配置查看http-proxy-middleware文档
其他的配置参数等信息,可以查看这里:https://github.com/chimurai/h…
*********************以上两种解决方式任选其一均可**************
关于环境,我还在hosts中配置了域名映射,使用了nginx帮我反向代理
可以参考我上一篇博文 https://www.cnblogs.com/yangw/p/11947752.html
未经作者 https://www.cnblogs.com/xin1006/ 梦相随1006 同意,不得擅自转载本文,否则后果自负