概念
跨域问题来源于浏览器的同源策略。客户端和服务端不同IP不同端口都算跨域。
假设没有同源, 互联网世界是什么样?参考对于浏览器的同源策略你是怎样理解的呢? - 知乎
- 链接跳转导致的问题.
http://a.com , 放一个链接到 icbc.com, 然后 window.open来打开, 获取窗口句柄, 然后可以拥有对这个页面完全的控制权. 拦截表单,捕获数据,将账号密码上传到a.com.
- ajax请求, 要啥就有啥.
你登录jd.com; 然后打开a.com, 通过ajax 请求http://jd.com 的用户信息接口, 这时候因为访问的jd.com,所以浏览器自动带上了jd的cookie,然后获取到你的订单list ,昵称, 所有私密信息.
所以,需要要同源策略
在同一个域内,客户端脚本可以任意读写同源内的资源,dom,cookie;但是不同的域,就不行
springboot解决跨域有cros,配置就是那几项。
nginx
如果把服务端程序部署在nginx上,在nginx 也可以解决,服务端和nginx只用写一个即可,
server
{
listen 3002;
server_name localhost;
location /ok {
proxy_pass http://localhost:3000;
# 指定允许跨域的方法,*代表所有
add_header Access-Control-Allow-Methods *;
# 预检命令的缓存,如果不缓存每次会发送两次请求
add_header Access-Control-Max-Age 3600;
# 带cookie请求需要加上这个字段,并设置为true
add_header Access-Control-Allow-Credentials true;
# 表示允许这个域跨域调用(客户端发送请求的域名和端口)
# $http_origin动态获取请求客户端请求的域 不用*的原因是带cookie的请求不支持*号
add_header Access-Control-Allow-Origin $http_origin;
# 表示请求头的字段 动态获取
add_header Access-Control-Allow-Header $http_access_control_request_headers;
}
}
值得一提的是,客户端如果要在跨域请求中携带cookie时,客户端发起请求要配置withCredentials=true,但如果配置了此参数,服务端 Access-Control-Allow-Origin 就不能是 *,所以上边nginx Access-Control-Allow-Origin没有写*。
Access-Control-Allow-Origin 是客户端请求来源,可以指定路径配置。
假设前端程序部署在172.20.0.206nginx上,监听80端口路由到前端。
服务端配置的Access-Control-Allow-Origin:http://172.20.0.206, 就可以访问正常访问了。
跨域配置不能重复
如果nginx加了跨域,nginx代理的web服务也加了跨域配置,反而会出现跨域问题,只能在一个地方加。笔者多次碰到这个问题,后端加了、nginx也加反而出问题。
nginx不管再server标签、还是location标签,最好也只加一处。