五种跨域的解决方法

跨域

jsonp

  • 前端:新建script标签 通过src发送请求 返回函数调用
    代码:
    1234
    我是新增的
    我也是新增的
    1234---------------------
    function jsonp(obj) {

    参数

    ​ obj.type = obj.type || ‘get’;

    ​ obj.url = obj.url || ‘’;
    let data = { …obj.data };

    把对象转换成字符串的形式

    ​ var arr = [];
    for (var k in data) {
    arr.push(${k}=${data[k]})
    }
    obj.url = ${obj.url}?${arr.join('&')};

    动态创建script标签

    ​ var script = document.createElement(‘script’);
    script.src = obj.url;
    document.body.appendChild(script)
    window[data.cb] = function (data) {

    window[data.cb] 是全局的 目的是把cb里的参数当做函数名,后台返回的show() 去调用 因为cb里的参数不固定,所以以data.cb的形式 相当于 function show(){} obj.success(data) 里的success会自动去调用jsonp里的success

    ​ return obj.success(data)
    }
    }
    jsonp({
    url: ‘http://localhost:3000/say’,
    data: {
    wd: ‘zs’,
    cb: ‘show’
    },
    success: function (data) {
    console.log(data)
    }
    })

  • 后端:
    返回函数名调用的形式 数据通过实参传递
    代码:
    let express = require(‘express’);
    let app = express();
    app.get(‘/say’, function (req, res) {
    let { wd, cb } = req.query;
    // console.log(wd)
    // res.send(‘ok’)
    res.end(${cb}(123))
    })
    app.listen(3000, () => {
    console.log(‘启动成功’)
    })

cors

  • cors 是后端做的操作, 需要为头做一些处理,告诉浏览器一些相关信息。
  • 1.告诉浏览器哪个源可以访问我
    res.setHeader(‘Access-Control-Allow-Origin’, origin)

  • 2.告诉浏览器允许携带哪个头可以访问我
    res.setHeader(‘Access-Control-Allow-Headers’, ‘name’)

  • 3.允许哪个请求方法访问我。 浏览器默认支持get post方法
    put 方法两次
    第一次:试探 询问 options
    第二次:发送ajax请求
    res.setHeader(‘Access-Control-Allow-Methods’, ‘PUT’);

  • 4.是否允许携带cookie
    res.setHeader(‘Access-Control-Allow-Credentials’, true);

postmessage

实现步骤:

  • 首先通过iframe标签向端口4000的b页面发送请求 但是无法传送数据 因为跨域
  • 然后获取iframe标签 利用contentWindow.postMessage向子页面b发送内容 postMessage里面有两个参数 第一个是发送的内容 第二个是规定向哪个页面发送内容
  • 接着子页面b通过window.onmessage接收到a发送的内容
  • 再接着通过e.source.postMessage向a页面发送内容响应内容
  • 最后a页面通过window.onmessagej接收到内容 存储在e.data
a页面
<body>
    <iframe src="http://localhost:4000/b.html" onload="load()" id="box"></iframe>
    <!-- <iframe src="http://localhost:4000/b.html" onload="load()" id="frames"></iframe> -->
</body>
<script>

    function load() {
        let frams = document.querySelector('#box')
        frams.contentWindow.postMessage('我爱你', 'http://localhost:4000/b.html');
        window.onmessage = function (e) {
            console.log(e.data);
        }
    }
b页面:
	   window.onmessage = function (e) {
            console.log(e);
            e.source.postMessage('我不爱你', e.origin)
        }

name

实现步骤:

  • a页面通过iframe引入子页面c发送请求 页面可以过来但是c页面里的内容不能引入过来,因为端口号不同,所以无法请求
  • 在端口4000的c页面上挂载window.name
  • 接下来就是a页面要拿到c页面的window.name里的内容
    • 获取iframevar frame = document.querySelector('#frames')
    • 直接通过frame.contentWindow会出现跨域的问题
    • 然后让a页面指向一个同域的b页面frame.src = 'http://localhost:3000/b.html'
    • 通过frame.contentWindow拿到b页面里的name
    • 因为是c页面和b页面的window是共享的 所以b可以拿到c的name
    • 然后a就可以通过同域的b页面拿到c里面的name
<body>
    <!-- <iframe src="http://localhost:4000/c.html" onload="load()" id="frames"></iframe> -->

    <iframe src="http://localhost:4000/c.html" onload="load()" id="frames" frameborder="0"></iframe>
</body>
<script>
    var first = true
    function load() {
        var frame = document.querySelector('#frames')
        if (first) {
            frame.src = 'http://localhost:3000/b.html'
            first = false
        } else {
            console.log(frame.contentWindow.name);
        }
    }
c页面
    <script>

        window.name = '我爱你啊'
    </script>

hash

hash:是地址栏#号后面的内容 称为hash

  • a页面通过iframe向c页面发送请求加上#后面的hash内容
  • c页面收到后 a页面接收到不因为跨域
  • 然后c页面又向b页面发送请求iframe.src = 'http://127.0.0.1:3000/b.html#idontloveyou';
  • b页面与a页面同域 b页面通过window.parent.parent.location.hash找到父级的a页面
  • a页面通过window.onhashchange (只要hash发生变化就会触发这个事件)
  • 最后a就可以通过location.hash 把hash内容打印出来
a页面
<body>
    <iframe src="http://localhost:4000/c.html#iloveyou" frameborder="0"></iframe>
    
</body>
<script>
    
    window.onhashchange = function () {
        console.log(location.hash)
    }  
</script>
c页面:
        // var iframe = document.createElement('iframe');
        // iframe.src = 'http://localhost:3000/b.html#idontloveyou';
        // document.body.appendChild(iframe)
b页面:
	window.parent.parent.location.hash = location.hash
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

殿君不是殿军

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值