手撕题之 JSONP

85 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第6天,点击查看活动详情

其实我在面试的时候没碰见过写 JSONP 的,但每次面试前我都会写一次

实现原理

利用script可以跨域请求实现,通过动态插入script标签,将src属性设置为目标请求,插入dom中,服务器接受该请求并返回数据,数据通常被包裹在回调钩子中,然后浏览器解析 script并执行后端返回的回调+数据,而jsonp也因为是依赖scirpt实现,而script标签请求资源只支持get请求,所以jsonp无法使用post请求

实现代码

<body></body>
<script>
  // index.html  http://127.0.0.1:5500/index.html
  
  const jsonp = (url, params, cbName) => {
    const script = document.createElement("script");
    window[cbName] = (data) => {
      // do something
      console.log("back " + data);
      document.body.removeChild(script);
    };
    params = { ...params, callback: cbName };
    const arr = Object.keys(params).map((key) => `${key}=${params[key]}`);
    script.src = `${url}?${arr.join("&")}`;
    document.body.appendChild(script);
  };
  
  jsonp("http://127.0.0.1:8000", {}, "callback");
</script>

相同原理

  1. <link herf="url"></link>
  2. <img src="url"></img>

上面这个两个加载资源的标签同jsonp,不受跨域限制

也可以使用 iframe解决

使用场景

  1. 用于解决前端和后端交互数据时出现的跨域问题
  2. 现在常用与一些老浏览器不支持CORS时采用的针对GET请求的跨域解决方案(即 JSONP 不支持 POST

JSONP 为什么不能发送 POST

jsonp因为是依赖scirpt实现,而script元素请求资源只支持get请求,所以jsonp无法使用post请求