JSONP 解决跨域问题

100 阅读1分钟

JSONP 的原理是利用了浏览器加载 JavaScript 资源文件时不受同源策略的限制而实现的。

具体实现方式:

  1. 全局注册一个函数,window.jsonpCallback = (data) => console.log(data)

  2. 构造一个请求 目标地址?callback=jsonpCallback

  3. 构造一个 script 标签,将 src 属性设置为上一步构造的请求地址,然后将 script 标签插入 DOM 中。

/** 示例 */
function jsonp(url){
  return new Promise((resolve, reject) => {
    window.jsonpCallback = (data) => {
      resolve(data);
    }

    const script = document.createElement('script');
    script.src = `${url}?callback=jsonpCallback`;

    script.onload = () => {
      script.remove()
    }

    script.onerror = () => {
      reject(new Error('error'))
    }

    document.body.appendChild(script);

  })
}

// 发送请求
jsonp("http://localhost:8888/data").then(response => {
  console.log("这是 JSONP");
  console.log(response);
});

  1. 服务器端构造一个 JavaScript 函数调用表达式并返回。
/**  使用 Node.js 做服务端来做一个示例 */


/**
    ...
*/

if (path === '/data') {
    response.statusCode = 200;
    response.setHeader("Content-Type", "text/javascript;charset=utf-8");
    
    const string = `window['{{xxx}}']({{data}})`
    // 使用json 数据做一个数据模拟
    const data =  fs.readFileSync("./public/data.json").toString();
    // 构造返回一个函数调用表达式   window.jsonpCallback(data)
    const finalString =  string.replace("{{data}}", data).replace('{{xxx}}', query.callback);
    response.write(finalString);
    response.end();
}

/**
    ...
*/

  1. 浏览器会加载并执行上述返回的代码(window.jsonpCallback(data))。

Github Demo