JSONP实现跨域

首先说一下什么是跨域

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

那么:跨域应该如何解决呢,通常跨域有两种解决办法,一种是利用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('服务器已经启动成功');
});

客户端:



    
        
        
        
        Document
    
    
        

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

执行结果:

JSONP实现跨域_第1张图片

 封装:

这里我们对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})
});

结果

JSONP实现跨域_第2张图片

 

你可能感兴趣的:(javascript,服务器,运维,ajax跨域问题)