Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

能否使用JSONP+代理方案解决跨域问题? #11

Open
PIKACHUIM opened this issue Nov 26, 2024 · 0 comments
Open

能否使用JSONP+代理方案解决跨域问题? #11

PIKACHUIM opened this issue Nov 26, 2024 · 0 comments

Comments

@PIKACHUIM
Copy link

一个 JSONP 的步骤实质

客户端发送 script 请求,参数中带着处理返回数据的回调函数的名字 (通常是 callback),如请求 script 的 url 是:
http://127.0.0.1:8000/?callback=getMsg
服务端收到请求,以回调函数名和返回数据组成立即执行函数的字符串,比如:其中 callback 的值是客户端发来的回调函数的名字,假设回调函数的名字是 getMsg,返回脚本的内容就是:
getMsg("{name: 'Yang Min', age: '8'}");
客户端收到 JavaScript 脚本内容后,立即执行脚本,这样就实现了获取跨域服务器数据的目的。
很明显,由于 JSONP 技术本质上利用了 script 脚本请求,所以只能实现 GET 跨域请求,这也是 JSONP 跨域的最大限制。
由于 server 产生的响应为 json 数据的包装(故称之为 jsonp,即 json padding),形如:getMsg("{name: 'Yang Min', age: '8'}")

JSONP 封装

客户端参考代码:

const jsonp = ({ url, params, callbackName }) => {
  const generateURL = () => {
    let dataStr = "";
    for (let key in params) {
      dataStr += `${key}=${params[key]}&`;
    }
    dataStr += `callback=${callbackName}`;
    return `${url}?${dataStr}`;
  };
  return new Promise((resolve, reject) => {
    // 初始化回调函数名称
    callbackName =
      callbackName ||
      "cb" +
        Math.random()
          .toString()
          .replace(".", "");
    let scriptEle = document.createElement("script");
    scriptEle.src = generateURL();
    document.body.appendChild(scriptEle);

    // 绑定到 window 上,为了后面调用
    window[callbackName] = data => {
      resolve(data);
      // script 执行完了,成为无用元素,需要清除
      document.body.removeChild(scriptEle);
    };
  });
};

jsonp({
  url: "http://127.0.0.1:8000/",
  params: {
    name: "Yang Min",
    age: "8"
  },
  callbackName: "getData"
})
  .then(data => JSON.parse(data))
  .then(data => {
    console.log(data); // {name: "Yang Min", age: "8"}
  });
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant