产生跨域请求问题的原因
因为在浏览器中有一个同源策略,这是浏览器最基本的安全功能,但是在服务器中不限制。
同源就是指:协议,域名,端口号都相同,任意一个不满足,就触发了同源策略,我们把触发了同源策略的请求叫做跨域请求
解决跨域请求的方式
-
jsonp
因为凡是具有src属性的标签都能够跨域,不受浏览器的同源策略的影响,所以jsonp的实现原理就是:1.动态创建一个script标签指向一个需要访问的地址2.实现一个全局函数来接收数据<script src="http://domain/api?param1=a¶m2=b&callback=jsonp""></script> <script> //函数名与地址的cb或者callback的值一致 function jsonp(res){ console.log(res) } </script>
jsonp的使用简单且兼容性不错,但是仅限于get请求
在开发中可能会遇到多个 JSONP 请求的回调函数名是相同的,这时候就需要自己封装一个 JSONP,以下是简单实现
<script> function jsonp(url,cbName,success){ let scr=document.createElement("script"); scr.src=url; scr.async=true; scr.type="text/javascript"; window[cbName]=function(res){ success&&success(res) } document.body.appendChild(scr); } jsonp("http://XXXX","函数名字",res=>{console.log(res)}) </script>
-
CORS(Cross-Origin ResourceSharing)
CORS是跨域资源共享,定义了必须在访问跨域资源时,浏览器与服务器应该如何沟通。
CORS的基本思想就是使用自定义的HTTP头部让浏览器与服务器进行沟通,从而决定请求或响应是应该成功还是失败。 目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。
实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。
服务器端对于CORS的支持,主要就是通过设置Access-Control-Allow-Origin来进行的。该属性表示哪些域名可以访问资源,如果设置通配符则表示所有网站都可以访问资源。如果浏览器检测到相应的设置,就可以允许Ajax进行跨域的访问。//在后端接口中设置 header('Access-Control-Allow-Origin:域名'); //当域名为*时支持所有网站都可以访问资源
-
nginx代理跨域
原理:同源策略只存在在浏览器中,对服务器不限制。
实现思路: 通过nginx配置一个代理服务器(域名与domain1相同,端口不同)做跳板机,反向代理访问domain2接口,并且可以顺便修改cookie中domain信息,方便当前域cookie写入,实现跨域登录。#proxy服务器 server { listen 81; server_name www.domain1.com; location = /gx { //正向代理,/gx是代理标识符,当发起请求时相当于url proxy_pass http://172.0.0.1/text/cors.php; } location / { proxy_pass http://www.domain2.com:8080; #反向代理 proxy_cookie_domain www.domain2.com www.domain1.com; #修改cookie里域名 index index.html index.htm; # 当用webpack-dev-server等中间件代理接口访问nignx时,此时无浏览器参与,故没有同源限制,下面的跨域配置可不启用 add_header Access-Control-Allow-Origin http://www.domain1.com; #当前端只跨域不带cookie时,可为* add_header Access-Control-Allow-Credentials true; } }
WebSocket与NodeJs中间件跨域等其他方法
这些方法除了nodejs用得都不是特别多,WebSocket不会专门用来做跨域,而是作为消息推送或者聊天等.