要说跨域,首先要提到浏览器的同源策略,因为是同源策略限制了跨域。同源策略就是说,浏览器请求到server1的一个页面,这个页面里面有对另一个源server2有资源的请求,浏览器会拦截这个请求的响应。同源则是指 协议+主机+端口号相同的情况。同源策略能够有效防止XSS攻击和CSRF攻击
在AJAX请求出现之后,我们的前端请求变得非常复杂,使得很多后台安全漏洞曝光了,
那为什么有跨域有风险还是要跨域呢,一方面是前后端分离,前后端的域名不一致,产生跨域问题,第二方面就是服务器端的负载均衡,将服务器分离为web静态资源服务器、数据服务器、图片服务器之类的,请求就要跨域。
有跨域的需求就驱动了解决方法的产生。平时项目里我主要接触的是AJAX跨域,主流的方法是CORS跨源资源共享 和 proxy跨域代理(jsonp已经比较古老了,实际应该没怎么使用)
JSONP是利用 script标签不存在跨域限制来做到的,只能使用 get请求(现在请求已经很复杂了,一个get满足不了需求)
- 具体就是通过url拼接一个函数,传递给服务器,服务器将数据放到函数的参数列表里,返回给客户端后再执行
CORS跨域资源共享
CORS需要浏览器和服务器都支持才行
对于我们前端开发者来说,CORS 通信与同源的 AJAX 通信没有差别,代码完全一样。浏览器一旦发现 AJAX 跨域的请求,会根据请求的不同来自动添加不同的请求头部字段
- 简单请求,像方法是head,get,post这三种,还有请求头部字段也有几个限制(6个基本头部字段) ,这样的请求,浏览器在头部字段中添加origin字段标明这个请求来自哪个源,之后就直接发送了
- 服务器返回的响应主要是多出三个头字段信息:都以 Access-Control- 开头
- Access-Control-Allow-Origin的值要么是请求时origin字段,要么是*表示接收任意域名的请求
- Access-Control-Allow-Credentials就是让允许浏览器发送cookie
- Access-Control-Expose-Headers主要是让XMLHttpRequest对象的getResponseHeader()拿到除了6个基本字段之外的字段。
- 服务器返回的响应主要是多出三个头字段信息:都以 Access-Control- 开头
- 非简单请求,请求比较复杂,会在正式通信之前,增加一次 HTTP 查询请求,称为 “预检” 请求,浏览器先询问服务器能否接受这样的请求:当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP 动词和头信息字段,满足这些条件后才可以发送正式请求
- 正式请求和简单请求过程一样
因此,实现 CORS 通信的关键是服务器。只要服务器实现了 CORS 接口,就可以跨源通信。