九种跨域方式的实现原理,第一个就超惊艳!( 四 )

上述代码经过两次跨域,值得注意的是浏览器向代理服务器发送请求,也遵循同源策略,最后在index.html文件打印出 {"title":"fontend","password":"123456"}
6.Nginx反向代理
实现原理类似于Node中间件代理,需要你搭建一个中转nginx服务器,用于转发请求 。
使用nginx反向代理实现跨域,是最简单的跨域方式 。只需要修改nginx的配置即可解决跨域问题,支持所有浏览器,支持session,不需要修改任何代码,并且不会影响服务器性能 。
实现思路:通过nginx配置一个代理服务器(域名与domain1相同,端口不同)做跳板机,反向代理访问domain2接口,并且可以顺便修改cookie中domain信息,方便当前域cookie写入,实现跨域登录 。
先下载nginx,然后将nginx目录下的nginx.conf修改如下:
// proxy服务器server { listen 80; server_name www.domain1.com; 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; }}最后通过命令行 nginx-s reload启动nginx// index.htmlvar xhr = new XMLHttpRequest();// 前端开关:浏览器是否读写cookiexhr.withCredentials = true;// 访问nginx中的代理服务器xhr.open('get', 'http://www.domain1.com:81/?user=admin', true);xhr.send();// server.jsvar http = require('http');var server = http.createServer();var qs = require('querystring');server.on('request', function(req, res) { var params = qs.parse(req.url.substring(2)); // 向前台写cookie res.writeHead(200, { 'Set-Cookie': 'l=a123456;Path=/;Domain=www.domain2.com;HttpOnly' // HttpOnly:脚本无法读取 }); res.write(JSON.stringify(params)); res.end();});server.listen('8080');console.log('Server is running at port 8080...');7.window.name + iframe
window.name属性的独特之处:name值在不同的页面(甚至不同域名)加载后依旧存在,并且可以支持非常长的 name 值(2MB) 。
其中a.html和b.html是同域的,都是 http://localhost:3000;而c.html是 http://localhost:4000 。
// a.html(http://localhost:3000/b.html) <iframe src=https://www.isolves.com/it/cxkf/bk/2019-07-01/"http://localhost:4000/c.html" frameborder="0" onload="load()" id="iframe"> b.html为中间代理页,与a.html同域,内容为空 。
// c.html(http://localhost:4000/c.html) <script> window.name = '我不爱你'</script>总结:通过iframe的src属性由外域转向本地域,跨域数据即由iframe的window.name从外域传递到本地域 。这个就巧妙地绕过了浏览器的跨域访问限制,但同时它又是安全操作 。
8.location.hash + iframe
实现原理: a.html欲与c.html跨域相互通信,通过中间页b.html来实现 。三个页面,不同域之间利用iframe的location.hash传值,相同域之间直接js访问来通信 。
具体实现步骤:一开始a.html给c.html传一个hash值,然后c.html收到hash值后,再把hash值传递给b.html,最后b.html将结果放到a.html的hash值中 。同样的,a.html和b.html是同域的,都是 http://localhost:3000;而c.html是 http://localhost:4000 。
// a.html <iframe src=https://www.isolves.com/it/cxkf/bk/2019-07-01/"http://localhost:4000/c.html#iloveyou"> // b.html // c.html console.log(location.hash); let iframe = document.createElement('iframe'); iframe.src = 'http://localhost:3000/b.html#idontloveyou'; document.body.appendChild(iframe);9.document.domain + iframe
该方式只能用于二级域名相同的情况下,比如 a.test.com 和 b.test.com 适用于该方式 。只需要给页面添加 document.domain='test.com' 表示二级域名都相同就可以实现跨域 。
实现原理:两个页面都通过js强制设置document.domain为基础主域,就实现了同域 。


推荐阅读