跨域产生的原因根本原因是由于浏览器的同源策略 。
同源策略/SOP(Same origin policy)是一种约定,由Netscape公司1995年引入浏览器,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,浏览器很容易受到XSS、CSRF等攻击 。所谓同源是指"协议+域名+端口"三者相同,即便两个不同的域名指向同一个ip地址,也非同源 。
解决方法方法一:通过jsonp跨域
前端JS原生实现:
<script>var script = document.createElement('script');script.type = 'text/JAVAscript';// 传参一个回调函数名给后端,方便后端返回时执行这个在前端定义的回调函数script.src = https://www.isolves.com/it/aq/fwq/2019-12-27/'http://www.domain2.com:8080/login?user=admin&callback=handleCallback';document.head.AppendChild(script);// 回调执行函数function handleCallback(res) {alert(JSON.stringify(res));}
node服务端实现
let querystring = require('querystring');let http = require('http');let server = http.createServer();server.on('request', function(req, res) {let params = qs.parse(req.url.split('?')[1]);let fn = params.callback;// jsonp返回设置res.writeHead(200, { 'Content-Type': 'text/JavaScript' });res.write(fn + '(' + JSON.stringify(params) + ')');res.end();});server.listen('8080');console.log('Server is running at port 8080...');
缺点:只能使用get请求,安全性差
方法二:document.domain + iframe跨域
实现原理:两个页面都通过js强制设置document.domain为基础主域,就实现了同域 。
缺点:此方案仅限主域相同,子域不同的跨域应用场景 。
代码实现:
//父页面:(http://www.domain.com/a.html)<iframe id="iframe" src=https://www.isolves.com/it/aq/fwq/2019-12-27/"http://child.domain.com/b.html">//子窗口:(http://child.domain.com/b.html)
此外还有 location.hash + iframe跨域、window.name + iframe、postMessage等跨域方式 。大伙可以自行网上查阅 。
方法三:Nginx代理跨域
nginx配置解决iconfont跨域
浏览器跨域访问js、css、img等常规静态资源被同源策略许可,但iconfont字体文件(eot|otf|ttf|woff|svg)例外,此时可在nginx的静态资源服务器中加入以下配置 。
//nginx配置解决iconfont跨域location / {add_header Access-Control-Allow-Origin *;}
nginx反向代理接口跨域
跨域原理: 同源策略是浏览器的安全策略,不是HTTP协议的一部分 。服务器端调用HTTP接口只是使用HTTP协议,不会执行JS脚本,不需要同源策略,也就不存在跨越问题 。
实现思路:通过nginx配置一个代理服务器(域名与domain1相同,端口不同)做跳板机,反向代理访问domain2接口,并且可以顺便修改cookie中domain信息,方便当前域cookie写入,实现跨域登录 。
nginx具体配置:
#proxy服务器server {listen81;server_namewww.domain1.com;location / {proxy_passhttp://www.domain2.com:8080;#反向代理proxy_cookie_domain www.domain2.com www.domain1.com; #修改cookie里域名indexindex.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;}}
前端代码示例:
var xhr = new XMLHttpRequest();// 前端开关:浏览器是否读写cookiexhr.withCredentials = true;// 访问nginx中的代理服务器xhr.open('get', 'http://www.domain1.com:81/?user=admin', true);xhr.send();
Nodejs后台示例:
var 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));// 向前台写cookieres.writeHead(200, {'Set-Cookie': 'l=a123456;Path=/;Domain=www.domain2.com;HttpOnly'});res.write(JSON.stringify(params));res.end();});server.listen('8080');console.log('Server is running at port 8080...');
方法三:Nodejs中间件代理跨域
node中间件实现跨域代理,原理大致与nginx相同,都是通过启一个代理服务器,实现数据的转发,也可以通过设置cookieDomainRewrite参数修改响应头中cookie中域名,实现当前域的cookie写入,方便接口登录认证 。
【分分钟了解跨域的几种处理方法】前端代码示例:
推荐阅读
- linux抓包工具tcpdup,对抓包结果作数据分析
- Ceph分布式存储安装部署过程
- 算法浅谈——人人皆知却很多人写不对的二分法
- 慢跑十分钟有锻炼效果吗
- 让人舒服的关系:知分寸、懂换位、付真心
- 解释什么是图灵测试 谈谈你了解的图灵测试,是谁第一个通过的这个测试
- 汽车副厂件和原厂件有何区别别再傻傻分不清
- 社保小知识,关于社保,这8个问题你也许想了解!
- 方向盘变沉了、打不动是怎么回事?几个常见的方向盘故障分析
- 农行绍兴分行小微金融服务助力茶企转型