JSONP能绕过同源策略,是因为它不使用XMLHttpRequest或fetch,而是动态插入标签加载远程脚本;浏览器不对的src做同源检查,只允许执行返回的JS代码(如callback({...})),从而实现跨域数据传递。

JSONP 能绕过同源策略,是因为它根本没用 XMLHttpRequest 或 fetch,而是靠动态插入 <script></script> 标签来加载远程资源。浏览器对 <script></script> 的 src 属性不执行同源检查,只关心能否下载并执行脚本——这正是 JSONP 的突破口。
为什么 <script></script> 可以跨域,而 AJAX 不行
同源策略(Same-Origin Policy)限制的是 JavaScript 对响应内容的读取权限,不是请求发起本身。AJAX 请求虽然能发出去,但浏览器会拦截响应体,禁止脚本访问跨域返回的数据。而 <script></script> 标签属于“资源加载”,它的目的不是获取数据,而是执行代码;只要服务端返回的是合法 JS 代码(比如调用一个已定义的回调函数),浏览器就允许执行,且不校验来源。
- 本质区别:AJAX 是「请求-响应-读取」流程,受 SOP 严格管控;JSONP 是「加载-执行」流程,属于白名单例外
-
<script></script>、、等标签从诞生起就被设计为可跨域加载资源,这是历史兼容性与功能需求共同决定的 - JSONP 的“数据”其实是嵌在 JS 执行逻辑里的——例如返回
callback({"name":"Alice"}),靠预设函数接收结果,不涉及 DOM 或响应体读取
JSONP 的主要安全隐患
正因为 JSONP 依赖脚本执行且无法验证响应来源,它天然存在多个高风险面:
- 任意脚本执行风险:一旦攻击者控制了目标 JSONP 接口(如域名劫持、CDN 投毒、服务端 XSS),就能注入恶意 JS,直接获取页面中所有敏感信息(cookie、localStorage、DOM 数据)
- 缺乏请求身份校验:JSONP 请求是纯 GET,无 Cookie 携带机制(除非显式开启 withCredentials,但 JSONP 本身不支持),也无 CORS 头校验,服务端很难区分合法调用和伪造请求
-
回调函数名可控导致劫持:若前端未固定 callback 名称(如允许 URL 参数传入
?callback=alert),攻击者可指定任意全局函数名,诱导页面执行非预期逻辑 - 无错误隔离机制:脚本加载失败(404/500/网络中断)或返回非法 JS 会导致全局报错,且无法通过 try-catch 捕获,影响页面稳定性
现代开发中如何规避 JSONP 风险
JSONP 已是遗留方案,主流场景应优先使用 CORS。但如果必须兼容老系统或受限环境,可采取以下缓解措施:
- 服务端严格校验
callback参数:只允许字母、数字、下划线,长度限制,拒绝含点号、括号、反斜杠等字符 - 避免在回调中处理敏感操作(如修改用户凭证、调用支付接口),JSONP 仅用于公开只读数据(如天气、公告)
- 前端使用唯一、随机生成的 callback 名(如
cb_1a2b3c),并配合定时器清理,防止被重复利用 - 配合 CSP(Content Security Policy)策略,限制
script-src仅允许可信域名,降低恶意脚本执行可能性











