序
在数据交互前后,经常会遇到跨域请求,什么是跨域,有哪几种跨域方式,这些都是本文要讨论的内容。

1.什么是跨域?
1.什么是同源策略及其限制内容?
同源策略是一种协议,是浏览器最核心、最基本的安全功能。如果没有同源策略,浏览器很容易受到XSS、CSRF和其他攻击。所谓同源,就是“协议+域名+端口”相同,即使两个不同的域名指向同一个ip地址,也不是同源。
相同的源策略限制包括:
cookie、本地存储、索引数据库和其他存储内容
DOM节点
AJAX请求发送后,结果被浏览器截获。
但是有三个标签允许跨域加载资源:
//b . html window . on message = function { console . log//我爱你e.source.postMessage}
4 .网络插座
Websocket是HTML5的持久性协议,实现浏览器和服务器的全双工通信,也是一种跨域的解决方案。WebSocket和HTTP都是应用层协议,都是基于TCP协议。然而,WebSocket是一种双向通信协议。连接建立后,WebSocket的服务器端和客户端都可以主动向对方发送或接收数据。同时,WebSocket在建立连接时需要HTTP协议的帮助。连接建立后,客户端和服务器之间的双向通信与HTTP无关。
原生webSocket API使用起来不是很方便。我们使用Socket.io,它很好的封装了webSocket接口,提供了更简单灵活的接口,也为不支持WebSocket的浏览器提供了向后兼容性。
让我们先举一个例子:本地文件socket.html生成并接收来自localhost:3000的数据。
//socket.html
//server . jslet express = require;让app =快递;设WebSocket = require//记得安装wslet wss = new WebSocket。服务器;WSS . on { ws . on { console . log;ws . send });})
5.节点中间件代理
实现原理:同源策略是浏览器需要遵循的标准,但如果服务器请求服务器,则不必遵循同源策略。
代理,您需要做以下步骤:
接受客户端请求。
将请求转发给服务器。
获取服务器响应数据。
将响应转发给客户端。
我们举个例子:本地文件index.html文件通过代理服务器http://localhost:3000向目标服务器http://localhost:4000请求数据。
//index.html
// server1.js代理服务器const http = require//第一步:接受客户端请求const server = http . createserver = > {//代理服务器,直接与浏览器交互,设置CORS头字段response.writeHead //第二步:将请求转发到服务器const proxy request = http . requestserveresponse . on = > { console . log//第四步:将响应结果转发到浏览器response.end})}。end })server . listen = > { console . log })
//server 2 . js const http = require const data = { title:' font end ',password:' 123456 ' } const server = http . create server = > { if { response . end)} })server . listen = > { console . log })
上面的代码已经跨域两次。值得注意的是,浏览器向代理服务器发送请求,同样遵循同源策略。最后,它打印出index.html文件中的{"title": "fontend "," password": "123456"}。
6.nginx反向代理
实现原理类似于节点中间件代理,需要你构建一个中转nginx服务器来转发请求。

使用nginx反向代理跨域是最简单的跨域方式。只需要修改nginx的配置就可以解决跨域问题,支持所有浏览器,支持session,不需要修改任何代码,也不会影响服务器的性能。
实现思路:通过nginx配置一个代理服务器作为跳板,反向代理访问domain2接口,顺便修改cookie中的域信息,方便当前域cookie写入,实现跨域登录。
先下载nginx,然后修改nginx目录下的nginx.conf,如下:
//代理服务器server { listen 80服务器名www.domain1.com;location/{ proxy _ pass http://www.domain2.com:8080;#反向代理proxy _ cookie _ domain www.domain2.com www.domain1.com;#修改cookie中的域名索引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;}}
最后,通过命令行nginx -s reload启动nginx。
//index . html var xhr = new XMLHttpRequest;//前端开关:浏览器是否读写cookie cookiexhr . with credentials = true;//访问nginx中的代理服务器xhr.openxhr.send
//server . jsvar http = require;var server = http.createServervar qs = requireserver . on { var params = QS . parse);//将cookie res.writeHead写到前台;RES . write);res.end});server.listenconsole.log
window.name + iframe
window.name属性的唯一性:加载不同页面后名称值依然存在,可以支持很长的名称值。
A.html和b.html属于同一个域,都是http://localhost:3000;c.html是http://localhost:4000。
//a.html
B.html是中间代理页面,与a.html同域,内容为空。
//c.html
总结:跨域数据通过iframe的src属性从外地域转移到本地域,即通过iframe的window.name从外地域转移到本地域。这样巧妙地绕过了浏览器的跨域访问限制,但同时又是一种安全的操作。
location.hash + iframe
实现原理:a.html想要和c.html跨域通信,可以通过中间页面b.html实现。三个页面,不同的域使用iframe的location.hash传递值,相同的域通过直接js访问相互通信。
实现步骤:首先,a.html发送一个哈希值给a.html,然后a.html接收哈希值,然后发送给a.html,最后a.html将结果放入a . html的哈希值中。
同样,a.html和b.html在同一个域,都是http://localhost:3000;c.html是http://localhost:4000。
//a.html
//b.html
//c.html console . log;设iframe = document.createElementiframe . src = ' http://localhost:3000/b . html # idontloveyu ';document . body . appendchild;
9 .文档.域+ iframe
这种方法只能在二级域名相同的情况下使用,如a.test.com和b.test.com。
只需在页面中添加document.domain ='test.com '表示二级域名全部相同,即可实现跨域。
实现原理:两个页面都通过js强制设置document.domain为基本主域,从而实现同域。
我们来举个例子:页面a.zf1.cn:3000/a.html获取页面b.zf1.cn:3000/b.html.中A的值
//a.html你好
//b.html你好
三。摘要

CORS支持所有类型的HTTP请求,是跨域HTTP请求的基本解决方案。
JSONP只支持GET请求。JSONP的优点是支持旧浏览器,从不支持CORS的网站请求数据。
无论是节点中间件代理还是nginx反向代理,服务器主要通过同源策略不受限制。
在日常工作中,cors和nginx反向代理是广泛使用的跨域方案。
来自简书:前方三少爷原文链接:https://www.jianshu.com/p/2896288494df


