跨域问题
MDN Web Docs 中定义跨域,当一个资源从与该资源本身所在的服务器不同的域或端口不同的域或不同的端口请求一个资源(script)时,资源会发起一个跨域 HTTP 请求。即访问了一个网站,然后在这个网站返回的资源里面,请求了B网站/端口的资源。
跨域限制这个情况只会出现在浏览器页面里,因为本质上是浏览器由于安全原因限制了这些请求的访问。
CSRF攻击,如果前端可以跨域,那:
用户访问A,生成cookie存储在本地,点击弹窗广告进入地址B,B网站可以在自己的页面中获取A的cookie,然后模拟用户登录
黑客利用Iframe把真正的银行登陆页面嵌到自己的页面上,他的页面可以通过JavaScript读取到用户表单上的内容
同源限制有:
(1) Cookie、LocalStorage 和 IndexDB 无法读取。
(2) DOM 无法获得。
(3) 请求的响应被拦截
在postman和APP里面,每发出一个请求,都是在独立请求一个资源,而不是在一个网站返回的页面里,再去请求另外一个网站/端口的资源。自然也就不会造成跨域了。
为什么要跨域?
因为不会把所有资源放在一台服务器上。
解决跨域的思路:
- 伪造域名
- 交给有能力跨域的代理,如服务器
- 找到浏览器不限制跨域的请求方式 JSONP、postMessage
- 找到跨域的资源共享的数据体
- 协调http协议,头部沟通允许跨域
document.domain
这个方法使用极其简单,但是只能用于主域相同的域之间的数据通信。【必须属于同一个基础域名,协议、端口都要相同】
当主域之间相互通信的时候,只要将两者的document.domain赋值为当前的主域地址,即可实现跨域通信。document.domain可以扩大范围,扩值不可逆
e.g:
http://a.yuhua.com:3000/a.html
http://b.yuhua.com:3000/b.html
代理服务器
跨域访问其实只是浏览器的同源策略,服务器没有这个限制
Node.js的http模块等都可以抓取其他网站的页面。
把前端Ajax需要跨域访问的地址交给后台服务器
Nginx
http代理服务、反向代理服务器(HTTP中间件)
正向代理:代理客户端发起请求。对客户端已知,对服务端透明(服务器不知道谁在访问)的代理应用,称为正向代理。如:梯子
反向代理:服务器内置几个服务器,用户去访问。
nginx反向代理处理请求实现跨域
解决前后端分离开发中,前端对接口联调中的跨域问题。
将nginx反向代理服务器部署在浏览器同源位置,在配置文件nginx.conf 中设置端口监听转发请求
vue-cli中的devServer和webpack dev server里面changeOrigin解决跨域实质上也是服务器代理,就类似Nginx反向代理这样
JSONP JSON with padding
< script >标签的src属性并不被同源策略所约束,可以获取任何服务器上脚本并执行。
jsonp的核心原理:允许在服务器端集成Script tags返回至客户端,通过javascript callback的形式实现跨域访问。相比img的图片探测,它可以实现双向通信。
本质是发起一个HTTP的GET请求。
jQuery也支持JSONP方法
jQuery.getJSON()
$.getJSON(url