javascript技巧

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript技巧 > JSONP同源策略跨域限制

JSONP解决同源策略限制引起跨域问题原理

作者:Qing

这篇文章主要为大家介绍了JSONP解决同源策略限制引起跨域问题原理解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

同源策略的限制引起跨域问题

同源策略

为了解决跨域问题,大家利用script标签请求src指向的资源不受同源策略限制的特性来进行资源的请求,这种方式就是JSONP。

接口实现

我们可以利用script标签请求资源不受同源策略限制的特性,可以自己简单的封装一个jsonp请求函数。
首先在js代码中手动创建script标签,把需要请求的资源放到src属性上,然后把script标签加入到body标签里面,在解析html的过程中就会执行,当执行完script并且请求到资源后,后端结果会以函数调用的的形式返回字符串类型的响应结果,这个形式的具体结构为函数名称(函数实参),和平时我们在调用函数时没有区别,然后页面就会执行后端返回的函数。

这里有个问题,页面会调用后端返回的函数,那么这个函数在哪里定义?

当然是要在本地的js代码里面定义这个函数,然后等待后端传递的参数,这个参数其实就是我们想要的返回结果。

// 简单写个序列化函数,不要就结是否考虑全面
function stringify(params) {
  let res = "";
  if (!params || typeof params !== "object") {
    throw new Error("请传递参数对象");
  }
  Object.keys(params).forEach((key) => {
    res += `&${key}=${params[key]}`;
  });
  return res.slice(1);
}
function jsonp({ url, params }) {
  return new Promise((resolve) => {
    const callback = `jsonp_${Math.ceil(Math.random() * 10000)}`;
    const script = document.createElement("script");
    script.src = `${url}?${stringify({ callback, ...params })}`;
    document.body.appendChild(script);
    // 一般情况下,函数的定义放置在window对象上,否则在调用函数的时候会找不到定义的实现
    window[callback] = function (data) {
      if (window[callback]) {
        delete window[callback];
      }
      document.body.removeChild(script);
      resolve(data);
    };
  });
}

发送JSONP请求

利用封装的jsonp发起请求

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width" />
    <title>jsonp请求</title>
  </head>
  <body>
    <button>点我就会biubiubiu地发送请求</button>
  </body>
  <script>
    const button = document.querySelector("button");
    button.onclick = function () {
      jsonp({ url: "http://localhost:8888" }).then(console.log);
    };
  </script>
</html>

服务端处理JSONP请求

jsonp请求需要服务端配合,约定查询参数callback是在本地定义好的函数,根据传递过来的callback返回其函数调用,并把数据通过实参的方式返回给客户端。

const http = require("http");
const url = require("url");
const qs = require("querystring");
const server = http.createServer((req, res) => {
  const { query } = url.parse(req.url);
  const params = qs.parse(query);
  if (params.callback) {
    const data = `${params.callback}(${JSON.stringify({ a: 1, b: 2 })})`;
    res.end(data);
  }
});
server.listen(8888, () => {
  console.log("server is listen 8888");
});

以上就是JSONP解决同源策略限制引起跨域问题原理的详细内容,更多关于JSONP同源策略跨域限制的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文