JavaScript学习 -- jsonp跨域请求

在现代 Web 应用程序的开发中,由于跨域访问的限制,经常需要在不同的域之间传输 JSON 数据。但是,浏览器强制遵循同源策略,限制了浏览器从一个域向另一个域请求数据的能力。为此,我们可以使用 JSONP(JSON with Padding)技术,它通过动态创建 script 标签实现了跨域传输 JSON 数据。

JSONP 实现了一个简单但非正式的协议,在客户端发出一个 GET 请求时,服务端返回一些 JavaScript 代码,使客户端能够利用这些代码执行回调。JSONP 非常适合用于构建跨域的 JSON 数据请求,但不能用于 POST 请求等其他类型的 Ajax 请求。本文将介绍如何在JavaScript中使用JSONP,并提供一个实际的例子。

实现JSONP

JSONP 可以通过以下代码实现:

function jsonp(url, callbackName, callback) {
  const script = document.createElement('script');
  script.src = `${url}?callback=${callbackName}`;

  window[callbackName] = (data) => {
    callback(data);
    document.body.removeChild(script);
  };

  document.body.appendChild(script);
}

我们可以看到,这个函数有三个参数:

  • url: JSONP 数据请求的 URL。

  • callbackName: 在服务端接受回调函数名的参数名。

  • callback: 接收 JSONP 数据的回调函数。

这个函数会动态地创建一个新的 script 标签,为获取 JSONP 数据请求 URL 添加一个查询参数 callback=callbackName。回调函数的名字将保留在查询参数中,以便服务端能够读取。

然后,在全局命名空间中,我们暴露这个名为 callbackName 的回调函数,并在脚本标签的 load 事件处理函数上执行这个函数。核心代码如下:

window[callbackName] = (data) => {
    callback(data);
    document.body.removeChild(script);
};

最后,我们再将新创建的 script 标签添加到文档中。因为该代码是通过 <script> 标签上定义的回调函数来执行的,所以这个 JSONP 请求的响应将被直接注入到我们的 JavaScript 中。

完整的代码如下:

function jsonp(url, callbackName, callback) {
  const script = document.createElement('script');
  script.src = `${url}?callback=${callbackName}`;

  window[callbackName] = (data) => {
    callback(data);
    document.body.removeChild(script);
  };

  document.body.appendChild(script);
}

jsonp('https://api.github.com/users/octocat', 'myCallback', (data) => {
  console.log(data);
});

在这个例子中,我们向 GitHub API 发送了一个 JSONP 请求,当响应返回时,在控制台打印响应数据。此外,我们利用服务端接受 callback=myCallback 参数,来创建了用于响应数据的回调函数。

JSONP 的优缺点

JSONP 的优点:

  • 浏览器支持良好,能在绝大多数环境下正常使用。

  • 不需要 Ajax 请求,无需 XMLHttpRequest 对象,不需要进行跨域 AJAX 的额外工作。

JSONP 的缺点:

  • 安全性问题。由于是在全局作用域上执行代码,所以恶意攻击者可以通过 JSONP 某些特定的接口来进行 CSRF(跨站请求伪造)。因此,我们需要在服务端进行一些针对性的安全策略。

  • 只支持 GET 请求,不能支持 POST 等其他类型的 AJAX 请求。

  • 只支持文本请求,不能传输二进制图像、JSON、XML 等类型的文件。

总结

JSONP 是一个使用非常广泛的跨域请求技术。通过简单的回调的方式,能方便地实现从不同域名的服务端动态地获得 JSON 数据。虽然使用起来比较方便,但也存在某些限制。JSONP 体现了一种传统 JavaScript 方式,如果不需要传输敏感数据或处理安全要求比较高的场景,我们仍然可以使用此技术。

相关推荐
_.Switch2 分钟前
高级Python自动化运维:容器安全与网络策略的深度解析
运维·网络·python·安全·自动化·devops
qq_254674414 分钟前
工作流初始错误 泛微提交流程提示_泛微协同办公平台E-cology8.0版本后台维护手册(11)–系统参数设置
网络
JokerSZ.7 分钟前
【基于LSM的ELF文件安全模块设计】参考
运维·网络·安全
cs_dn_Jie1 小时前
钉钉 H5 微应用 手机端调试
前端·javascript·vue.js·vue·钉钉
开心工作室_kaic2 小时前
ssm068海鲜自助餐厅系统+vue(论文+源码)_kaic
前端·javascript·vue.js
有梦想的刺儿2 小时前
webWorker基本用法
前端·javascript·vue.js
小松学前端3 小时前
第六章 7.0 LinkList
java·开发语言·网络
清灵xmf3 小时前
TypeScript 类型进阶指南
javascript·typescript·泛型·t·infer
城南vision3 小时前
计算机网络——TCP篇
网络·tcp/ip·计算机网络