为什么要限制跨域?
为了防止恶意网站获取用户在其他网站上的信息。
如果不限制,恶意网站通过ajax访问银行余额页面。解析返回的html就能拿到用户余额。
没有限制请求,限制的是获取信息。
所以form表单可以跨域,而ajax不能跨域。
form只是提交不获取返回结果,ajax要获取结果
为什么不限制请求?请求本来就不好限制,给你个csrf就诱导了请求。重要请求要做验证码,但是一些不重要的请求可能返回隐私信息。防的就是黑客获取隐私信息。
发生跨域的条件
- 浏览器限制
- 发出的请求跨域
- XHR请求
解决方法
针对上面三个条件的解决方法
- 浏览器限制
可以修改浏览器设置,但是无意义,不能修改所有用户的浏览器设置。 - 发出的请求跨域
- 修改被调用方(返回头,让浏览器支持跨域)
- 修改调用方(代理服务器转发?)
- XHR请求
JSON
1. JSONP【只支持get,过期】
返回js代码,发出的请求时script
AbstractJsonpResponseBodyAdvice 已经过期,推荐使用CORS
Will be removed as of Spring Framework 5.1, use CORS instead.
将callback值作为函数名返回。”_”参数防止被缓存。
jsonp只支持get请求。
2. 被调用方解决
2.1 服务器端实现
2.1.1 Filter 解决方案
跨域请求,请求头增加了origin 字段
编写filter 增加response 字段
2.1.1.1 简单请求&非简单请求
非简单请求的预检命令
非简单请求,会有“预检命令”
预检命令会发送 content-type method,看服务器是否支持此类型跨域。
预检命令缓存
2.1.1.2带cookie的跨域
- 当代cookie 时,Acces-Control-Allow-Origin 不能为* 号
- 增加Access-Control-Allow-Credentials:3600
问题:Acces-Control-Allow-Origin 不能为* 那其他跨域怎么办呢?
可以在filter中 获取request的origin字段,然后设置到response的Acces-Control-Allow-Origin 。
2.2 nginx配置
- 包括增加 响应头、
- 将origin和自定义header返回
- 处理预检命令OPTIONS
2.3 apache配置
略
2.4 spring 框架解决方案
@CrossOrigin
@CrossOrigin(origins = “ http://domain2.com“, maxAge = 3600)
3 调用方 解决方案
代理服务器
浏览器有跨域限制,服务器没有跨域一说。
浏览器请求到同域名的自己的nginx,ng转发到远程服务器。