JS | 跨域数据请求技术——JSONP详解

目录

写在前面

什么是 JSONP?

JSONP 的历史背景

JSONP 的优点和局限性

JSONP 的工作原理

JSONP 的实现步骤

客户端实现 callback 函数

服务端 JSONP 格式数据

JSONP 总结

JSONP 的安全性问题

JSONP 存在的安全隐患

如何保护 JSONP 请求的安全性

JSONP 的应用场景

跨域数据获取

与第三方 API 的集成

跨域数据分析与可视化

JSONP 与现代技术的关系

JSONP 与 CORS 的比较

JSONP 在现代 Web 开发中的地位

总结 


写在前面

当谈到 JSONP,就像是在谈论你在一场派对上认识的新朋友一样,让我们从头开始介绍。

什么是 JSONP?

JSONP,全称 “JSON with Padding”,译为“带回调的 JSON”,是一种利用 <script> 标签进行跨域数据请求的技术。它允许你在网页中请求来自其他域的数据,而无需担心浏览器的同源策略(Same-Origin Policy)带来的限制。

JSONP 不是一门编程语言,也不是什么特别的技术,它更像一个漏洞,程序员可以利用这个漏洞,实现跨域(可以简单理解为跨域名)传输数据。

JSONP 是 JSON 的一种使用模式,通过 JSONP 可以绕过浏览器的同源策略,进行跨域请求。

在进行 Ajax 请求时,由于同源策略的影响,不能进行跨域请求,而 <script> 标签的 src 属性却可以加载跨域的 JavaScript 脚本,JSONP 就是利用这一特性实现的。与普通的 Ajax 请求不同,在使用 JSONP 进行跨域请求时,服务器不再返回 JSON 格式的数据,而是返回一段调用某个函数的 JavaScript 代码,在 src 属性中调用,来实现跨域。

JSONP 的优点是兼容性好,在一些老旧的浏览器种也可以运行,但它的缺点也非常明显,那就是只能进行 GET 请求。

以一个简单的比喻来说,就像你在一家餐馆点菜一样。你可以在自己家里使用电话点餐,然后等着外卖送达,而不需要亲自去餐馆。JSONP允许你在当前页面中加载其他网站的数据,就像是通过电话点餐一样轻松。

  番外:何为「同源策略」 

同源策略是由 Netscape(网景) 提出的一个著名的安全策略,现在所有支持 JavaScript 的浏览器都会使用这个策略。

所谓同源是指域名、协议、端口都相同。以 http://www.xxxxx.com:80/ 为例,http:// 为协议,域名是 www.xxxxx.com,端口是80(提示:80 为默认端口,可以省略,若为其它端口则必须显示定义)。

为了安全,浏览器不允许进行跨域请求。当我们通过 Ajax 在网页和服务器之间发送或接收数据时,需要保证网页与所请求的地址是同源的,否则无法请求成功。同源策略可以防止 JavaScript 脚本从您的网站中读取数据,并将数据发送到其它的网站。如果没有同源策略,很有可能会有恶意的程序泄露您网站中的内容。

虽然同源策略在一定程度上提高了网站的安全,但也会给程序员带来一些麻烦,例如在访问一些开发接口时,由于同源策略的存在,会调用失败。要解决这种问题就需要用到跨域,跨域的方法有许多种,其中最经典的就是 JSONP。


JSONP 的历史背景

JSONP的历史可以追溯到当时的 Web 1.0 时代,这时候互联网还没有那么复杂。跨域请求并不是一个大问题,因为网页之间的交互性相对较少。但随着 Web 2.0 的兴起,网页变得更加交互和动态,跨域请求的需求也随之增加。

当时,JSONP就像是一位突然出现的超级英雄,解决了跨域请求的难题。它简单、有效,并且可以在各种浏览器上运行,这使得它迅速成为了 Web 开发人员的首选。


JSONP 的优点和局限性

JSONP的优点就像是一把多功能的瑞士军刀,帮助你轻松应对各种场景:

简单易用: JSONP的原理简单明了,几行代码就可以实现跨域请求。

兼容性好: JSONP在各种浏览器上都能良好运行,无需担心兼容性问题。

适用性广: JSONP不仅可以用于数据请求,还可以用于跨域数据分析和可视化等各种场景。

然而,就像是每个超级英雄都有自己的弱点一样,JSONP也有一些局限性:

仅支持 GET 请求: JSONP只能通过 <script> 标签发起 GET 请求,无法发送其他类型的请求,如 POST 请求。

安全性问题: JSONP存在安全隐患,因为它是通过动态插入 <script> 标签来加载数据的,可能被恶意利用来执行跨站脚本攻击(XSS)。
尽管有这些局限性,但在许多场景下,JSONP仍然是一个非常有用且方便的解决方案。


JSONP 的工作原理

让我们用一个生动的比喻来解释JSONP的工作原理,就像是在派对上传递纸条一样。

假设你在派对上认识了一个新朋友,但是你们无法直接交谈,因为你们被隔开了。你想要向他询问一些问题,但是你只能通过传递纸条来进行沟通。这就是JSONP的基本思想。

在Web开发中,当你需要从一个网站获取数据,但是由于浏览器的同源策略(Same-Origin Policy)限制,你无法直接进行跨域请求。JSONP的解决方案是利用 <script> 标签来加载远程数据,绕过了同源策略的限制,实现了跨域数据请求。

就像是你通过传递纸条来与派对上的朋友交流一样,JSONP通过动态创建 <script> 标签,加载包含数据的远程脚本,然后利用回调函数将数据传递给你的网页,实现了跨域数据的获取。


JSONP 的实现步骤

让我们用一个有趣的比喻来解释JSONP的实现步骤,就像是在操纵一台神奇的魔法机器一样。

客户端实现 callback 函数

创建回调函数

首先,你需要准备好一个魔法咒语,也就是你的回调函数。这个回调函数就像是一段魔法代码,会在你请求数据时被触发,并且接收到你想要的数据。

就像是在准备施展一场魔法一样,你需要先在网页的某个地方创建一个函数,比如叫做 handleData。这个函数会接收一个参数,用来接收服务器返回的数据。当数据到达时,这个函数就会被调用,就像是你在念咒语一样。

function handleData(data) {
   // 在这里处理接收到的数据
   console.log(data);
}

动态插入<script>标签

接下来,你需要操纵魔法机器,让它帮你完成跨域数据请求的任务。你会用到的工具就是 <script> 标签,这个标签有着神奇的能力,可以加载其他域名下的脚本。

就像是在操作一台魔法机器一样,你需要创建一个 <script> 标签,并将远程数据的URL作为它的src属性值。这样,浏览器就会开始下载并执行这个URL指定的脚本文件。

var oscript = document.createElement('script');
oscript.src = 'http://example.com/aaa?callback=handleData';
document.body.appendChild(oscript);

在这段代码中,我们创建了一个 <script> 标签,并设置了它的src属性为远程数据的URL,同时通过 callback=handleData 的参数告诉服务器,当数据准备好时,请调用我们之前准备好的魔法咒语 handleData。

请求数据

最后,当魔法机器收到你的指令时,它会开始运转,发送请求并等待服务器的响应。服务器收到请求后,会将数据包装在之前指定的回调函数中,并返回给你的网页。

就像是在等待魔法机器完成任务一样,你只需要耐心等待,当数据准备好时,你的魔法咒语 handleData 就会被触发,接收到你想要的数据。

function handleData(data) {
   console.log('收到数据:', data);
}

当数据准备好时,你会看到控制台输出了你想要的数据,就像是魔法成功施展一样。这就是JSONP的实现步骤,通过动态插入 <script> 标签,利用回调函数实现了跨域数据的请求和获取。

<!DOCTYPE html>
<html lang="en">
 
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
 
<body>
    <!-- jsonp接口调用 -->
    <script>
        var oscript = document.createElement("script")
        oscript.src = "http://localhost:3000/api/aaa?callback=handleData"
        document.body.appendChild(oscript)
 
        function handleData(obj) {
            console.log(obj);
        }
    </script>
</body>
 
</html>

服务端 JSONP 格式数据

var http = require("http")
var url = require("url")
 
http.createServer((req, res) => {
    var urlobj = url.parse(req.url, true)
    console.log(urlobj.query.callback);
    switch (urlobj.pathname) {
        case "/api/aaa":
            res.end(`${urlobj.query.callback} (${JSON.stringify({
                name: '张三',
                age: 21
            })})`)
            break;
        default:
            res.end("404")
    }
}).listen(3000, () => {
    console.log("start");
})

JSONP 总结

通过 jsonp,我们可以避开浏览器的同源策略,从而进行跨域请求。jsonp 是利用 HTML 标签的 src 属性引用资源不受同源策影响的特性来实现的,实现步骤如下:

① 通过动态创建 script 标签,其 scr 指向非同源的 url,并传递一个 callback 参数给服务端;

② 服务器返回一个以 callback 参数作为函数名的函数的调用和一系列参数;

③ 页面接收到响应后执行回调并对数据进行处理。

注意:服务器返回的内容,必须是一段可执行的 JavaScript 代码,不能是其它内容。 


JSONP 的安全性问题

让我们以一个有趣的比喻来解释JSONP的安全性问题,就像是在保护自己的城堡免受恶意入侵一样。

JSONP 存在的安全隐患

想象一下,你的城堡是你的网站,而城墙是浏览器的同源策略,它保护着你的城堡不受外界的侵扰。但是有一天,一群坏人试图利用城堡内的一个小门(JSONP)来进行入侵。

JSONP存在的安全隐患就像是城堡中的小门一样,它可以绕过浏览器的同源策略,允许从其他域名获取数据。但是如果没有妥善地保护这个小门,恶意攻击者可能会利用它来进行跨站脚本攻击(XSS)或者盗取用户的信息。

当你使用JSONP来加载远程脚本时,你其实是在邀请外界的数据进入你的网站,就像是开了城门一样。如果你不小心,可能会让不怀好意的数据进入你的网站,造成安全风险。

如何保护 JSONP 请求的安全性

为了保护你的城堡免受恶意入侵,你需要采取一些安全措施来保护JSONP请求的安全性。

首先,你可以在使用JSONP时谨慎选择可信任的数据源,就像是在选择你的盟友一样。确保你从可信任的服务器获取数据,避免从不信任的源加载脚本。

其次,你可以对从JSONP获取的数据进行严格的验证和过滤,就像是检查城堡门口的行人一样。确保你接收到的数据是你期望的格式和内容,避免恶意数据的注入和执行。

最后,你可以考虑使用其他安全性更好的替代方案,比如CORS(跨域资源共享)或者代理服务器,来替代JSONP。这些方案虽然可能更复杂一些,但是可以提供更高级的安全保护,避免了JSONP存在的一些安全隐患。

通过这些安全措施,你就可以有效地保护JSONP请求的安全性,确保你的网站免受恶意攻击的威胁。


JSONP 的应用场景

让我们以一个有趣的比喻来解释JSONP的应用场景,就像是在一场冒险中利用神奇道具一样。

跨域数据获取

假设你是一位勇敢的探险家,正在探索未知的领域。你需要从其他地方获取数据来了解这个世界的各种信息,但是你发现有些数据被限制在其他领域中,无法直接获取。

这时,JSONP就像是一把神奇的钥匙,可以打开这些数据的大门,让你轻松获取到需要的信息。你只需要通过JSONP发起跨域请求,就能够从其他领域获取到数据,而不受浏览器的同源策略限制。

与第三方 API 的集成

继续你的冒险之旅,你发现了一些强大的魔法道具,但是它们都受到了强大魔法的保护,无法直接使用。幸运的是,有些魔法道具的制造商提供了API接口,可以通过JSONP来访问。

这时,JSONP就像是一个能够与不同魔法道具对话的翻译官,帮助你与第三方API进行交流。你可以通过JSONP向API发送请求,获取到你需要的魔法道具,然后在你的冒险中加以利用。

跨域数据分析与可视化

你的冒险之旅取得了巨大的进展,你已经收集到了大量的数据,但是这些数据分散在不同的领域,你需要将它们集中起来进行分析和可视化。

JSONP就像是一位数据搜集者,帮助你将分散在各个领域的数据整合起来。你可以通过JSONP向不同的领域发送请求,获取到需要的数据,然后通过分析和可视化工具对数据进行处理和展示。


JSONP 与现代技术的关系

让我们以一个生动的比喻来解释JSONP与现代技术的关系,就像是在比较老牌武林高手与新生代新秀一样。

JSONP 与 CORS 的比较

想象一下,JSONP就像是一位古老的武林高手,他拥有独特的功夫,可以轻松应对各种挑战。而CORS则是一位新生代的武林新秀,他学习了现代武术,技艺高超,但还需要时间来证明自己。

JSONP的优势在于其简单易用,适用于各种场景。它就像是一把多功能的瑞士军刀,可以应对各种跨域请求的需求。但是JSONP只能发送GET请求,存在一些安全性问题,因此在某些情况下可能不够安全。

而CORS则是一种更为现代化的跨域解决方案,它通过在服务器端设置HTTP头部来实现跨域资源共享。CORS支持各种类型的HTTP请求,并且更为安全可靠。但是CORS需要服务器的支持,并且在一些老旧的浏览器上可能存在兼容性问题。

因此,在现代Web开发中,JSONP和CORS往往会根据具体的需求和场景进行选择。对于简单的跨域请求,JSONP可能更加适用;而对于复杂的跨域请求,CORS可能更为合适。

JSONP 在现代 Web 开发中的地位

尽管CORS等新技术逐渐崭露头角,但JSONP在现代Web开发中仍然占据着重要地位。它的简单易用和兼容性好,使得它在某些场景下仍然是首选的跨域解决方案。

特别是在与第三方API集成、数据分析与可视化等场景下,JSONP仍然是一种非常有效的解决方案。它可以帮助开发者轻松地从其他域获取数据,并且可以与各种前端框架和工具无缝集成,为Web开发带来了便利。

虽然JSONP可能不再是唯一的跨域解决方案,但它仍然是Web开发人员工具箱中的一把利器,为跨域请求提供了简单而有效的解决方案。


总结 

总的来说,JSONP作为一种跨域数据请求的解决方案,在现代Web开发中仍然具有重要的地位。通过动态插入 <script> 标签并利用回调函数,JSONP可以轻松地实现跨域数据获取,克服了浏览器的同源策略带来的限制。它简单易用、兼容性好,适用于各种场景,如与第三方API集成、跨域数据分析与可视化等。

❀ 参考资料 ❀

jsonp 详解 —— 终于搞懂 jsonp 了-优快云博客

所有人都应该知道的跨域及CORS

什么是跨域?一文弄懂跨域的全部解决方法-优快云

jsonp理解 -博客园 | 什么是JSONP - 简书

jsonp 原理详解及 jsonp-pro 源码解析

跨域数据请求技术JSONP详解_jsonp跨域-优快云博客

<think>嗯,用户现在想了解JSONP的工作原理以及它如何解决问题,还有和源的关系。之前用户已经提问过源的区别,我之前也回答过,现在需要结合引用的资料来详细解释JSONP。 首先,我需要明确用户的问题点:JSONP如何工作,为什么能解决,以及它和源的关系。根据提供的引用,用户给出的资料提到JSONP是一种早期解决方案,利用script标签不受同源策略限制的特性。同时,JSONP只支持GET请求,而CORS是官方标准,支持更多方法但兼容性差。 用户可能已经知道是由同源策略引起的,但需要更深入的理解JSONP的机制。可能需要从基本原理讲起,比如script标签可以加载资源,服务器返回的数据包裹在回调函数中,前端预先定义好回调函数,这样就能获取数据。同时需要对比JSONP和Ajax的不同,比如引用[2]提到JSONP没有使用XMLHttpRequest,所以不算Ajax。 还要注意用户提到的引用内容,比如jQuery中的JSONP实现,虽然设置type为jsonp,但实际还是GET,无法使用POST。这部分需要在回答中解释清楚。另外,需要指出JSONP的优缺点,比如兼容性好但安全性问题,只支持GET,容易被注入恶意代码。 用户可能还想知道JSONP源的关系,之前回答中提到源的子集,所以JSONP解决的是问题中的资源加载限制,属于源通信的一种方式。但需要强调JSONP主要用于数据请求,而其他源方法如postMessage用于不同窗口通信。 需要确保回答结构清晰,分点说明原理、流程、与/源的关系、优缺点,以及示例代码。同时,生成的相关问题要引导用户进一步了解CORS或其他方法,比如如何选择JSONPCORS,或者JSONP的安全隐患。 最后,检查是否所有引用资料都被合理引用,比如引用[1]提到JSONP前端程序员想出的临时方案,引用[3]的示例代码,引用[4]关于jQuery的实现方式等。确保回答准确,符合用户提供的资料,同时结合之前的回答内容,保持一致性。</think>### **JSONP 工作原理及与/源的关系** --- #### **一、JSONP 的核心原理** **JSONPJSON with Padding)** 是一种利用 `<script>` 标签**不受同源策略限制**的特性实现的数据请求技术[^1][^3]。其核心逻辑如下: 1. **动态创建 `<script>` 标签** 前端通过动态创建 `<script>` 标签,向目标服务器发起请求,并在 URL 中指定一个回调函数名(如 `callback=handleData`)[^3][^5]。 ```javascript function handleData(data) { console.log(data); } const script = document.createElement('script'); script.src = 'http://api.example.com/data?callback=handleData'; document.body.appendChild(script); ``` 2. **服务器返回包裹数据的函数调用** 服务器将返回的数据包裹在指定的回调函数中,格式为:`handleData({...})`。例如: ```javascript handleData({ name: "John", age: 30 }); ``` 3. **前端执行回调函数** 浏览器加载并执行该脚本时,自动调用预定义的回调函数 `handleData`,从而获取数据[^3][^4]。 --- #### **二、JSONP 如何解决问题** 1. **绕过同源策略限制** 浏览器禁止 AJAX 请求(如 `XMLHttpRequest`),但允许加载 `<script>`、`<img>` 等标签资源。JSONP 利用这一特性实现数据获取[^1][^2]。 2. **协议无关性** JSONP 通过普通的 HTTP 请求(GET)传递数据,无需依赖特定协议或复杂配置。 --- #### **三、JSONP源的关系** 1. **场景的典型解决方案** - JSONP 主要解决** HTTP 请求被拦截**的问题(如 AJAX 请求不同源接口)。 - 它属于广义的**源通信**手段,但仅适用于数据请求场景,无法实现 DOM 操作或 Cookie 读取[^1][^2]。 2. **与 CORS 的对比** | 特性 | JSONP | CORS | |--------------------|---------------------------|--------------------------| | **请求类型** | 仅支持 GET | 支持 GET、POST 等 | | **安全性** | 存在 XSS 风险(需信任服务端) | 依赖服务端配置,更安全 | | **兼容性** | 兼容老旧浏览器(如 IE8) | 需浏览器支持 CORS 标准 | | **实现复杂度** | 简单(前端+服务端约定回调)| 需服务端设置响应头 | --- #### **四、JSONP 的局限性** 1. **仅支持 GET 请求** 由于 `<script>` 标签本质是资源加载,无法实现 POST、PUT 等复杂请求[^1][^4]。 2. **安全性风险** - 若服务端返回恶意代码,可能引发 XSS 攻击。 - 需完全信任目标服务器的安全性[^3]。 3. **错误处理困难** 无法通过 HTTP 状态码捕获错误,需依赖超时机制或冗余代码[^5]。 --- #### **五、示例代码(jQuery 实现)** ```javascript $.ajax({ url: "http://api.example.com/data", dataType: "jsonp", // 声明为 JSONP 请求 jsonpCallback: "handleData", // 自定义回调函数名 success: function(data) { console.log("Received:", data); }, error: function() { console.error("Request failed"); } }); ``` **服务端响应示例**: ```javascript handleData({ status: 200, message: "Success" }); ``` --- ### **总结** - **JSONP 的本质**:利用 `<script>` 标签的能力,“欺骗”浏览器完成数据加载。 - **适用场景**:兼容老旧浏览器的简单 GET 请求,不涉及敏感数据的安全场景。 - **演进方向**:现代开发中,CORS 已逐渐取代 JSONP 成为主流方案[^1][^3]。 --- ### **相关问题** 1. 如何防范 JSONP 的 XSS 攻击风险? 2. 为什么 JSONP 不支持 POST 请求?能否通过其他方式模拟? 3. 在 CORS 普及的今天,JSONP 还有哪些实际应用场景? 4. JSONP 与 WebSocket 在源通信上的区别是什么? : 引用1 [^2]: 引用2 : 引用3 [^4]: 引用4 [^5]: 引用5
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

儒雅的烤地瓜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值