浅析 跨域解决方案

一、同源策略

  • 同源策略(SOP 全称 Same origin policy):是浏览器的一种安全策略

  • 所谓的同源策略,指 浏览器不允许非同源网址的访问

    • 域名 完全相同
    • 协议 完全相同
    • 端口号 完全相同
    • ( URL 中文件路径、锚点、查询字符串 等部分不同,不会影响访问 )
  • 同源策略限制以下几种行为:

    • Cookie、LocalStorage 和 IndexDB 无法读取
    • DOM 和 Js对象无法获得
    • AJAX 请求不能发送
  • 如果缺少了同源策略,浏览器很容易受到XSS、CSFR等攻击

二、跨域

  • 跨域: 就是非同源的网址 的正常访问(服务端没有跨域的需求)

  • 跨域出现的错误提示: Access-Control-Allow-Origin

  • 具有跨域能力的标签:

    • <script><img> 标签的 src 属性具有跨域请求能力
    • <link> 标签的 href 属性
    • <iframe> 标签
  • 需要跨域的场景:

|URL | 说明 | 是否允许通信|
| — | — | — |
http://www.domain.com/a.js
http://www.domain.com/b.js
http://www.domain.com/lab/c.js |同一域名,不同文件或路径 | 允许
http://www.domain.com:8000/a.js
http://www.domain.com/b.js | 同一域名,不同端口 | 不允许,需跨域
http://www.domain.com/a.js
https://www.domain.com/b.js | 同一域名,不同协议 | 不允许,需跨域
http://www.domain.com/a.js
http://192.168.4.12/b.js | 域名和域名对应相同ip | 不允许,需跨域
http://www.domain.com/a.js
http://x.domain.com/b.js
http://domain.com/c.js | 主域相同,子域不同 | 不允许,需跨域
http://www.domain1.com/a.js
http://www.domain2.com/b.js | 不同域名 | 不允许,需跨域

三、跨域解决方案

最全跨域参考

  • 概述:
    • jsonp 跨域
    • document.domain + iframe 跨域
    • location.hash + iframe 跨域
    • window.name + iframe 跨域
    • postMessage 跨域
    • 跨域资源共享(CORS)
    • nginx 代理跨域
    • nodejs中间件代理跨域
    • WebSocket 协议跨域
1. jsonp 跨域
  • 适用场景: 只能实现 GET 请求的跨域

  • 原理: 应用 <script> 标签的 src 属性 具有跨域请求能力,动态创建 <script> 标签;将 src 属性值定义为 需要跨域的 url;并将 <script> 标签 添加到文档流中

  • 原生js 实现jsonp跨域:

<script>

    var script = document.createElement('script');

    script.type = 'text/javascript';

    // 传参并指定回调执行函数为onBack
    script.src = 'http://www.domain2.com:8080/login?user=admin&callback=onBack';
    document.head.appendChild(script);

    // 回调执行函数(服务器返回时,即执行该函数)
    function onBack(res) {
        alert(JSON.stringify(res));
    }

</script>
  • jquery 实现jsonp跨域:
    • jquery 调用ajax方法时,发现 dataType: jsonp;便动态创建 <script> 标签
$.ajax({
    url: 'http://www.domain2.com:8080/login',
    type: 'get',
    dataType: 'jsonp',  // 请求方式为jsonp
    jsonpCallback: "onBack",    // 自定义回调函数名
    data: {}
});
  • vue.js 实现jsonp跨域:
this.$http.jsonp('http://www.domain2.com:8080/login', {
    params: {},
    jsonp: 'onBack'
}).then((res) => {
    console.log(res);
})
  • 后端node.js 实现jsonp跨域:
var querystring = require('querystring');
var http = require('http');
var server = http.createServer();

server.on('request', function(req, res) {
    var params = qs.parse(req.url.split('?')[1]);
    var 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...');
2. document.domain + iframe 跨域
  • 适用场景: 只能实现 主域相同、子域不同 的跨域

  • 原理: 两个页面都通过js 强制设置document.domain为基础主域,从而实现了同域

  • 缺陷: 允许主子域脚本进行通信,但不涉及 localStorage 、indexedDB 和 XMLHttpRequest 的共享

  • 代码展现:

  • (1) 父窗口 http://www.domain.com/a.html

<iframe id="iframe" src="http://child.domain.com/b.html"></iframe>

<script>
    document.domain = 'domain.com';
    var user = 'admin';
</script>
  • (2) 子窗口 http://child.domain.com/b.html
<script>

    document.domain = 'domain.com';
    // 获取父窗口中变量
    alert('get js data from parent ---> ' + window.parent.user);
</script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值