JSONP 教程

JSONP(JSON with Padding)是一种跨域请求数据的解决方案,主要用于浏览器 绕过同源策略 进行跨域请求。它利用 <script> 标签的特点,让浏览器可以从不同源加载数据。


1. 为什么需要 JSONP?

同源策略的限制

  • 默认情况下,浏览器禁止 JavaScript 向 不同域 发送 AJAX 请求。例如: $.get("https://api.example.com/data", function(response) { console.log(response); }); 如果 api.example.com 与当前页面的域名不同,则请求会被浏览器阻止!

JSONP 的解决方案

JSONP 通过 <script> 标签动态加载远程脚本,把数据作为 JavaScript 代码执行。
服务器返回的数据格式会被包装成一个回调函数,浏览器执行后即可获取数据。


2. JSONP 的工作原理

假设我们有一个 JSONP API(https://api.example.com/data?callback=myCallback),服务器返回如下数据:

myCallback({
    "name": "Alice",
    "age": 25
});

浏览器会执行 myCallback(),这样前端就能获得跨域数据。


3. 使用 jQuery 进行 JSONP 请求

使用 $.ajax() 方法

$.ajax({
    url: "https://api.example.com/data",
    dataType: "jsonp",  // 关键点:使用 JSONP
    jsonp: "callback",  // 告诉服务器回调参数的名称(通常是 callback)
    success: function(response) {
        console.log("跨域数据:", response);
    },
    error: function() {
        console.log("请求失败");
    }
});


使用 $.getJSON()

jQuery 提供了 $.getJSON() 方法来简化 JSONP 请求:

$.getJSON("https://api.example.com/data?callback=?", function(response) {
    console.log("跨域数据:", response);
});

注意

  • callback=?:jQuery 会自动生成一个回调函数名,并替换 ?

4. 服务器端如何支持 JSONP?

如果你是后端开发者,需要让服务器支持 JSONP。以下是不同语言的 JSONP 服务器示例:

Node.js(Express)

const express = require("express");
const app = express();

app.get("/data", (req, res) => {
    const callback = req.query.callback; // 获取回调函数名
    const data = { name: "Alice", age: 25 };
    res.type("application/javascript");
    res.send(`${callback}(${JSON.stringify(data)})`);
});

app.listen(3000, () => console.log("服务器运行在 3000 端口"));

PHP

<?php
$data = array("name" => "Alice", "age" => 25);
$callback = $_GET["callback"]; // 获取回调函数名
echo $callback . "(" . json_encode($data) . ");";
?>


5. JSONP 的局限性

  • 只能用于 GET 请求,无法发送 POST 数据。
  • 安全风险:JSONP 可能被恶意利用执行攻击代码(XSS)。
  • 服务器端支持:后端 API 必须专门处理 JSONP 请求,返回格式需符合 JSONP 规范。
  • 现代替代方案:JSONP 逐渐被 CORS(跨域资源共享) 取代,CORS 更加安全且支持 GETPOST 等多种请求方式。

6. JSONP vs CORS

JSONPCORS
请求方式只能使用 GET支持 GETPOST
安全性易受 XSS 攻击更安全
服务器支持服务器需要返回 JSONP 格式服务器只需设置 Access-Control-Allow-Origin
推荐使用旧浏览器兼容性较好现代浏览器建议使用

✅ 推荐使用 CORS,只有在后端不支持 CORS 时才考虑 JSONP。


7. 结论

  • JSONP 通过 <script> 标签实现跨域数据请求,适用于 GET 请求。
  • jQuery 提供了 $.ajax()$.getJSON() 方法来简化 JSONP 调用。
  • 服务器端必须返回回调函数格式的数据,如 callback({ json 数据 })
  • CORS 更安全,更推荐使用,JSONP 主要用于兼容老旧 API。

如果可能,尽量使用 CORS 来解决跨域问题,而不是 JSONP。


🔹 示例总结

$.ajax({
    url: "https://api.example.com/data",
    dataType: "jsonp",
    success: function(response) {
        console.log(response);
    }
});

📌 服务器返回格式

myCallback({
    "name": "Alice",
    "age": 25
});

这样,JSONP 就可以绕过同源限制,获取跨域数据!🚀


💡 如果你的 API 不能修改,且不支持 JSONP,建议使用代理服务器或 CORS。