JSONP解决跨域

一、同源政策

1.什么是同源

如果两个页面拥有相同的协议、域名和端口,那么这两个页面就属于同一个源,其中只要有一个不同,就是不同源

2.同源政策的目的

同源政策是为了保证用户信息的安全,防止恶意的网站窃取数据。最初的同源政策是指A网站在客户端设置的Cookie,B网站是不能访问的

随着互联网的发展,同源政策也越来越严格,在不同源的情况下,其中有一项规定就是无法向非同源地址发送Ajax请求,如果请求,浏览器就会报错。

二、使用JSONP解决同源限制问题

1.什么是JSONP

JSONP是json with padding的缩写,它不属于ajax请求,但是它可以模拟ajax请求 ,是一个非官方的跨域解决方案,且只支持get请求

2.JSOPN怎么工作的

有一些网页的标签具体有跨域能力,例如:img、link、iframe、script

JSOPN就是利用script的跨域能力来发送请求

3.JSONP的使用

(1)将不同源的服务器端请求地址写在script标签的src属性中

<script src="www.example.com"></script>

(2)服务器端响应数据必须是一个函数的调用,真正要发送给客户端的数据需要作为函数调用的参数

(3)在客户端全局作用域下定义函数fn

function fn (data){}

  将函数定义放在script标签前面,且定义在全局作用域中

(4)在fn函数内部对服务器返回的数据进行处理

  三、JSOPN代码优化

1.将script发送请求变为动态请求

<body>
    <button>点击发送请求</button>
    <script>
        function fn(data){
            console.log('客户端函数被调用');
            console.log(JSON.stringify(data));
        }
    </script>
    <!-- 将非同源服务器端的请求地址写在script的src属性中 -->
    <script>
        const btn = document.querySelector('button');
        btn.onclick = function(){
            const script = document.createElement('script');
            script.src = 'http://localhost:3000/server2';
            document.body.appendChild(script);
            //避免重复发送
            script.onload = function(){
                document.body.removeChild(script);
            }
        }
    </script>
</body>

2.客户端需要将函数名称传递到服务器端

以免客户端修改函数名字影响服务器端去反复修改

    <button>点击发送请求</button>
    <script>
        function fn(data){
            console.log('客户端函数被调用');
            console.log(JSON.stringify(data));
        }
    </script>
    <script src="http://localhost:3000/server2_1?callback=fn"></script>
app.get('/server2_1',(req, res) => {
    res.setHeader('Access-Control-Allow-Origin', '*');
    const fnName = req.query.callback;
    const result = fnName  + '({name:"张宇灿"})';
    res.send(result);
})

3.封装jsonp函数,方便发送请求

jsonp.js

function jsonp(options){
    //动态创建script标签
    const script = document.createElement('script');
    //为script添加src属性
    script.src = options.url;
    //将script追加到页面中
    document.body.appendChild(script);

    //当jsonp加载完成后删除script标签
    script.onload = () =>{
        document.body.removeChild(script);
    }
}

    <button>点击发送请求</button>
    <script src="../../jsonp.js"></script>
    <script>
        function fn(data){
            console.log('客户端函数被调用');
            console.log(JSON.stringify(data));
        }
    </script>
    <script>
        const btn = document.querySelector('button');
        btn.onclick = function(){
            jsonp({
            url:'http://localhost:3000/server2_1?callback=fn'
        })
        }
    </script>

4.函数与封装的jsonp函数关联、函数

  jsonp中成功/失败时调用函数已经不是全局函数
    生成随机的函数名字,防止多次调用jsonp函数时,后边的覆盖前边的

function jsonp(options){
    //动态创建script标签
    const script = document.createElement('script');
    //jsonp中成功/失败时调用函数已经不是全局函数
    //随机的函数名字,防止多次调用jsonp函数时,后边的覆盖前边的
    const fnName = 'myJsonp' + Math.random().toString().replace('.','');
    window[fnName] = options.success; 
    //为script添加src属性
    script.src = options.url + '?callback=' + fnName;
    //将script追加到页面中
    document.body.appendChild(script);

    //当jsonp加载完成后删除script标签
    script.onload = () =>{
        document.body.removeChild(script);
    }
}

5.将请求参数拼接到请求地址的后边

  //拼接请求参数到地址后边
    var params = '';
    for(var attr in options.data){
        params += '&' + attr + '=' + options.data[attr];
    }
    script.src = options.url + '?callback=' + fnName + params;

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值