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

 更新时间:2023年08月04日 10:31:14   作者: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同源策略跨域限制的资料请关注脚本之家其它相关文章!

相关文章

  • 聊聊Javascript中try catch的2个作用

    聊聊Javascript中try catch的2个作用

    try...catch 可以测试代码中的错误,try 部分包含需要运行的代码,而catch部分包含错误发生时运行的代码,这篇文章主要给大家介绍了关于Javascript中try catch的2个作用,需要的朋友可以参考下
    2021-09-09
  • js实现简单拼图游戏

    js实现简单拼图游戏

    这篇文章主要为大家详细介绍了js实现简单拼图游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-07-07
  • JavaScript清空数组的四种方法

    JavaScript清空数组的四种方法

    这篇文章主要介绍了JavaScript清空数组的四种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-03-03
  • JavaScript比较当前时间是否在指定时间段内的方法

    JavaScript比较当前时间是否在指定时间段内的方法

    这篇文章主要介绍了JavaScript比较当前时间是否在指定时间段内的方法,涉及javascript时间与字符串的转换及比较操作相关技巧,需要的朋友可以参考下
    2016-08-08
  • js对象合并的4种方式与数组合并的4种方式

    js对象合并的4种方式与数组合并的4种方式

    这篇文章主要介绍了js对象合并的4种方式与数组合并的4种方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-10-10
  • 一文让你快速了解JavaScript栈

    一文让你快速了解JavaScript栈

    这篇文章主要介绍了一文让你快速了解JavaScript栈,栈全称为堆栈,是一种先进后出的的数据结构,栈中只有两种基本操作,也就是插入和删除,也就是入栈和出栈操作,栈只有一端可以进行入栈和出栈操作,我们将其称为栈顶,另一端称其为栈底
    2022-07-07
  • 微信小程序收货地址API兼容低版本解决方法

    微信小程序收货地址API兼容低版本解决方法

    这篇文章主要介绍了微信小程序收货地址API兼容低版本解决方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-05-05
  • JS检测数组类型的方法小结

    JS检测数组类型的方法小结

    这篇文章主要介绍了js检测数组类型的方法小结,有instanceof方法Array.isArray() 方法和Object.prototype.toString.call()方法,都是比较常用的,需要的朋友可以参考下
    2017-03-03
  • 微信小程序实现评价功能

    微信小程序实现评价功能

    这篇文章主要为大家详细介绍了微信小程序实现评价功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-08-08
  • js实现扫雷源代码

    js实现扫雷源代码

    这篇文章主要为大家详细介绍了js实现扫雷源代码,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-11-11

最新评论