JSONP实现跨域

本文详细介绍了跨域的概念以及两种常见的解决方法,重点讲解了JSONP的工作原理和实现步骤。通过示例展示了如何在客户端和服务器端配合使用JSONP进行跨域请求,最后还提供了JSONP的封装方法以提高代码复用性。此外,文章也提及了服务器端使用`res.jsonp`的便捷方式。
摘要由CSDN通过智能技术生成

首先说一下什么是跨域

跨域就是在客户端在访问服务器的时候,出现了协议、域名、端口有一项或者几项不同,就会导致跨域。也就是说,在这种情况下,跨域会阻止你的访问。向服务器发送请求后,也自然不会收到服务器返回的数据了。

那么:跨域应该如何解决呢,通常跨域有两种解决办法,一种是利用JSONP来实现跨域,另外就是使用CORS来实现跨域。

JSONP(JSON with Padding)实现跨域

原理:jsonp实现跨域的原理,就是利用script标签可以实现跨域访问,我们在使用script标签的时候,有时会直接引用外部资源,那么为何能够直接访问呢。原因就是script自带跨域啊。所以利用script标签里面的src属性就可以实现跨域访问,但是jsonp跨域只能用于get请求,这当然也是由于script使用的也是get请求了。

做法:

首先我们使用express来搭建一个小服务器用来演示。

const express = require('express');

const app = express();

app.get('/person', (req, res) => {
    // 接收请求参数里面的函数名称
    // 这里需要保证客户端和服务端的函数名称一致
    // 函数声明在客户端,服务端来调用,并且传参。
    var fnName = req.query.callback;
    // 客户端将数据返回给服务端
    res.send(fnName + '({name:"paul",age:23})');
});
app.listen(8001, function () {
    console.log('服务器已经启动成功');
});

客户端:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
    </head>
    <body>
        <div id="app">
            <button>点我发送请求</button>
            <div id="box"></div>
        </div>
        <script>
            // 函数声明
            function fn(data) {
                console.log('我已经收到了数据');
                console.log(data);
            }
            const btn = document.querySelector('button');
            const box = document.getElementById('box');
            btn.addEventListener('click', () => {
                // 创建script标签
                const script = document.createElement('script');
                // 将script标签的src属性设置为要访问的地址
                // 函数名称通过请求参数传给服务端
                script.src = 'http://localhost:8001/person?callback=fn';
                // 在页面中插入标签
                box.appendChild(script);
                // 访问完成移除标签
                script.onload = function () {
                    box.removeChild(script);
                };
            });
        </script>
    </body>
</html>

在执行过程中插入script标签,并且完成请求,接收到数据后再移除script标签。

执行结果:

 封装:

这里我们对jsonp的操作进行简单封装。

           // 封装jsonp
            function jsonp(options) {
                // 传递参数,需要拼接在请求地址后面
                var params = '';
                for (var attr in options.data) {
                    params += '&' + attr + '=' + options.data[attr];
                }
                // 生成一个随机名字,确保每次定义的函数不重名。以防发生数据覆盖。
                var fnName =
                    'jsonp' + Math.random().toString().replace('.', '');
                // 将success函数传给window.fn(),fn()就是success别名当调用了fn就会调用                            
                //success
                // 也就是将success变成全局函数,同时还有名字
                window[fnName] = options.success;
                const script = document.createElement('script');
                script.src = options.url + '?callback=' + fnName + params;
                document.body.appendChild(script);
                script.onload = function () {
                    document.body.removeChild(script);
                };
            }
            // 调用封装的jsonp
            btn.addEventListener('click', function () {
                jsonp({
                    url: 'http://localhost:8001/person',
                    data: {
                        address: 'xian',
                    },
                    success: function (data) {
                        console.log(data);
                    },
                });
            });

对jsonp的封装方便了我们的使用

服务端可以直接使用jsonp方法


app.get('/person', (req, res) => {
    // 接收请求参数里面的函数名称
    // 这里需要保证客户端和服务端的函数名称一致
    // 函数声明在客户端,服务端来调用,并且传参。
    // var fnName = req.query.callback;
    // 客户端将数据返回给服务端
    // res.send(fnName + '({name:"paul",age:23})');
    res.jsonp({name:'paul',age:25})
});

结果

 

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值