• 通过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>
  • 相关阅读:
    Fibonacci Again
    N的10000的阶乘
    HDU2141(二分搜索)
    POJ2366(HASH法)
    10106 Product
    UVA 401 Palindromes
    UVA424 Integer Inquiry
    POJ2503(二分搜索)
    mysql重置root密码
    tidb安装haproxy负载均衡
  • 原文地址:https://www.cnblogs.com/chydream/p/15155894.html
Copyright © 2020-2023  润新知