跨域问题和由浏览器的同源策略CORS
在前后端分离的开发中我们经常会遇到这样的问题
前后端分离的时候,前段的AJAX请求不能发送。
后端:拍着胸脯说我的接口肯定没有问题,我用postman都测过啦,可以请求的!
前端:跨域问题,一定是后端的锅,我的配置没有问题,傻逼。
所以跨域问题是前后端同学都必须要了解的
跨域问题是由浏览器的同源策略导致的
同源策略要求客户端和服务端的协议,域名,端口相同
- 协议相同。如果一个使用http一个使用https 或者file
- 域名相同。一个是goole 一个是goole.com
- 端口相同。客户端请求得端口要和服务器监听的端口相同
想要解决跨域问题需要用到一个W3c标准,CORS跨域资源共享协议
cors它允许浏览器向跨源服务器发出请求
它分为
- 预请求
什么是预请求 预请求什么时候发生
处于跨域环境并在下面几个条件下,
1.使用了某些方法,比如说 PUT, DELETE 等。
2.Fetch 规范规定了,对 CORS安全的首部字段集合,人为设置会触发预请求。
3.Content-Type的值不是text/plain ,multipart/form-data,application/x-www-form-urlencoded
浏览器会发送两个请求给服务器;
首先,客户端要发送 OPTIONS 请求 给服务器。
在服务器内部,需要对 OPTIONS 请求 ,做出一些设定 ,允许哪些方法访问。然后告诉客户端
如果客户端确认服务器允许该方法,就会发起最终请求;否则,抛出错误,服务器拒绝访问此方法。
预请求保证了服务器的安全性,让服务器可控制客户端访问的内容 - 非预请求
在跨域产生的条件下,某些请求和方法,不需要预请求,只发送一个请求就行了。比如简单的请求:GET, POST, HEAD 这三个方法。
CORS跨域资源共享协议如何解决跨域问题
后端:
对于非预请求只需要设置响应首部字段 Access-Control-Allow-Origin: | *
其中,origin 参数的值指定了允许访问该资源的外域 URL,*表示允许来自所有域的请求。这样做的好处是服务器可以设置某一IP的客户端进行访问,也可以设置某一域名下的客户端进行访问。
对于预请求响应首部字段 ‘Access-Control-Allow-Origin’: ‘*’, // 允许访问该资源的外域
‘Access-Control-Allow-Methods’: ‘*’, // 允许访问 的方法
‘Access-Control-Allow-Headers’: ‘Content-Type’//设置
会触发 预请求 ,虽然是 POST 方法,但是 Content-Type 为 application/json
总结起来CORS 就是在 HTTP 协议内部,新增了若干个 首部字段 ,来制定跨域资源共享规则 。
response.setHeader
- 第二种解决方案就是常见的 JSONP 解决方案,这种解决方案呢?
<script >
标签访问时,可以跨越这些同源策略限制,但只能使用 GET 方法:<script>
标记来引用一个外部的JS文件
利用<script>
标签,规避跨域,<script src="url"><script>
标记来引用一个外部的JS文件。我们只需要在客户端js代码中声明一个函数,function jsonCallback() {}。在跨域请求时,服务端根据客户端传来的信息,查找数据库,然后返回数据并调用 jsonCallback() 函数将字符串返还给客户端,客户端自行解析为JS代码。
但是这个方法有一个缺点就是它只能发送get请求。
- 第三种解决方案是
:使用服务器代理解决跨域问题,原理是:服务器不用遵守浏览器的同源策略,然后服务器代理分为(正向代理与反向代理)
1. 接受客户端 请求 。
2. 将 请求 转发给服务器。
3. 拿到服务器 响应 数据。
4. 将 响应 转发给客户端。