文章内容基于个人总结,如有问题欢迎评论。
1.何为跨域
关于网站的跨域问题,简单的说就是不同协议(如http|https)不同域名(如www.a.com|www.b.com|a.b.com)或者不同端口号(:3000|3001)之间的请求访问,都会产生同源限制导致请求失败。
2.解决方案
下面展示5种解决方案(包含代码及部分思路)
1) jsonp 根据script标签请求不会产生同源限制的原理 (局限在于只能发送get请求,及请求长度有限制)
客户端:
服务器端:
router.all('/jsonp', function(req, res, next) { var callback = req.query.jsonp; var obj = {name: 'tom', hobby: [1,2,3]}; res.send(callback ? callback + '(' + JSON.stringify(obj) + ')' : 'jsonp response');});
思路: 在客户端先定义好callback方法,将方法作为url参数传到服务器端,服务器端返回方法调用并回传参数让客户端方法处理。
2) cors跨域 设置Access-Control-Allow-[Origin|Methods|Headers]等参数开启跨域许可
客户端:
服务器端:
router.all('/cors', function(req, res, next) { res.header("Access-Control-Allow-Origin", "*"); // 最简设置 res.json('cors response');});
3) iframe + window.name
客户端:
服务器端:
router.all('/', function (req, res, next) { res.json('api response');});
思路: 比较重要的一步是iframe页和请求页需要设置相同的domain, 即代码中执行的document.domain = 'localhost'这一段。
4) iframe + postMessage
客户端:
思路: 这里win.postMessage是给iframe发送消息,直接的postMessage是给自己发送消息。如果在iframe页面想给本页面发消息,则需要用window.parent.postMessage发送消息。
5) nginx反向代理
这个方式的实现就是修改下nginx配置,如
server { listen 3001; server_name localhost; location /api { proxy_pass http://127.0.0.1:3000/api; }}
通过这种设置就把本地3001端口的请求映射到3000端口去,然后就可以正常的发送之前同源限制的api接口了, 如客户端代码:
3. 总结
基本的几种方式就是这样,当然都是一些抛砖引玉的小实现思路,具体问题还是得具体分析的。然后,一些代码用到了像es6语法或者fetch api,有看不懂的。。还是补补课吧,毕竟还是比较通用流行的了。