前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >通过jsonp解决跨域的源码实现及其特点

通过jsonp解决跨域的源码实现及其特点

作者头像
用户1272076
发布2021-09-08 16:00:30
6540
发布2021-09-08 16:00:30
举报
文章被收录于专栏:张培跃张培跃

一、Jsonp的特点

1、Jsonp是解决跨域的方式之一。

2、Jsonp的核心则是动态添加<script>标签来调用服务器提供的js脚本,所以兼容性非常好。

3、Jsonp只支持get请求。

4、Jsonp在调用失败的时候不会返回各种HTTP状态码。

5、在请求完毕后通过调用callback的方式回传结果,将回调方法的权限给了调用方。所以在调用jsonp接口时,需要与被调用方协商好用于callback的参数名字,参数的值为函数名。例如cb=_jsonp1234。cb为双方约定好的参数名,_jsonp1234指定被调用方所要执行的函数名。所以调用方在调用前要保证已方拥有该函数用于接收值。

二、通过Promise封装Jsonp

代码语言:javascript
复制
/*
* 实现对 Jsonp 的封装
* url:请求地址
* params:传递的参数对象
* jsonp:与服务端协商的用于存放函数名字的参数
* */
export default function jsonp({url = "", params = {}, jsonp = "cb"}) {
    return new Promise((resolve, reject) => {
        // 定义 body 用于接收数据
        let  body = null;
        // 自定义函数的名字
        const cbName = "_jsonp" + Math.random().toString(36).substr(2);
        // 将jsonp放入params
        params[jsonp] =  cbName;
        // 自定义函数,用于接收值
        window[cbName] = function (data) {
            body = data;
        }
        function _handler({type}){
            // 删除script标签
            document.body.removeChild(script);
            // 删除自定义的函数
            delete window[cbName];
            // 加载完毕并得到数据执行resolve
            console.log(1111,body)
            if(type === "load" && !body)  resolve(body);
            // 异常执行 reject
            else if(type === "error") reject("加载失败");
        }
        // 将对象转为urlencoded格式
        const urlencoded = Object.keys(params).map(v => v + "=" + params[v]).join("&");
        // 将地址url与参数进行拼接。
        url += (url.includes("?") ? "&" : "?") + urlencoded;
        // 创建 script 标签
        const script = document.createElement("script");
        script.src = url;
        // 加载完毕
        script.onload = _handler;
        // 加载异常
        script.onerror = _handler;
        // 指定类型
        script.type = 'text/javascript';
        // 脚本可用,异步执行
        script.async = true;
        // 创建好的script放入body.
        document.body.appendChild(script);
    })
}

三、前端调用

通过百度jsonp的接口进行调用测试:

代码语言:javascript
复制
<script type="module">
    import jsonp from "./jsonp.js";
    // https://www.baidu.com/sugrec?prod=pc&wd=web前端&cb=cb
    (async () => {
        try {
            const res = await jsonp({
                url: "https://www.baidu.com/sugrec",
                params: {
                    prod: "pc",
                    wd: "web前端",// 指定关键字
                },
                jsonp: "cb"
            });
            console.log(res);
        } catch (err) {
            console.log(e)
        }
    })();
</script>
本文参与?腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-08-17,如有侵权请联系?cloudcommunity@tencent.com 删除

本文分享自 张培跃 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与?腾讯云自媒体同步曝光计划? ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
http://www.vxiaotou.com