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


    一、Jsonp的特点

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

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

    3、Jsonp只支持get请求。

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

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

    二、通过Promise封装Jsonp

    /*
    * 实现对 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的接口进行调用测试:

    <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>
  • 相关阅读:
    android代码控制seekbar的样式
    在Android中显示GIF动画
    一个带动画效果的颜色选择对话框控件AnimatedColorPickerDialog
    史上最强Android 开启照相或者是从本地相册选中一张图片以后先裁剪在保存并显示的讲解附源码
    Linux System Programming note 8 ——File and Directory Management
    Spring它不支持依赖注入static静态变量
    举例说,在命令模式(Command Pattern)
    log4j 日志大小限制 分成30一个 不按日期分日志 按大小分成 按生产日期
    JavaScript获取路径
    awk与sed:关于多行的样本
  • 原文地址:https://www.cnblogs.com/chydream/p/15155894.html
Copyright © 2020-2023  润新知