jsonp接口必须限制回调函数名,因其依赖浏览器对标签的信任,若不校验callback参数,攻击者可传入恶意js代码执行;thinkphp通过白名单机制(如config/app.php配置或控制器动态指定)强制校验,未命中则静默返回纯json。

JSONP接口为什么必须限制回调函数名
ThinkPHP 默认开启 JSONP 支持时,callback 参数会直接拼入响应头和响应体,若不校验,攻击者可传入任意 JavaScript 代码(如 callback=alert(1) 或 callback=document.write('<script src="//xss.com"></script>')),触发前端执行恶意脚本。这不是 ThinkPHP 特有漏洞,而是 JSONP 协议本身的设计缺陷——它依赖浏览器对 <script></script> 标签的信任,所以服务端必须做白名单过滤。
ThinkPHP 5.1+ 如何配置 JSONP 白名单回调函数
从 ThinkPHP 5.1 开始,json` 方法不再自动信任任意 callback 参数,需显式启用并指定白名单。关键点是:不能只靠中间件或控制器逻辑判断,必须在 JSONP 输出前完成校验。
-
json()方法默认不启用 JSONP,需手动传参:$this->json($data, 200, [], ['jsonp' => true]) - 白名单通过配置项
jsonp_callback控制,推荐在config/app.php中设置:'jsonp_callback' => ['getInfo', 'getList', 'getData'] - 若需动态控制(比如按模块不同白名单),可在控制器中覆盖:
$this->json($data)->jsonp(['getUser', 'getProfile']) - 未命中白名单时,ThinkPHP 会静默忽略
callback参数,返回纯 JSON(状态码仍为 200),不会报错也不会提示
ThinkPHP 6.x 的 JSONP 白名单更严格,但默认关闭
TP6 移除了全局 json` 的自动 JSONP 检测,callback 参数完全不会被解析,除非你主动调用 jsonp() 方法。这意味着:不写这行代码,就不可能产生 JSONP 响应。
使用 JSON Schema 验证 JSON 数据,从示例 JSON 生成 schema,并将其转换为 TypeScript 接口、Python 数据类或 Markdown 文档。
- 启用方式:
return json($data)->jsonp('callback_name');—— 注意这里第一个参数是字符串,不是数组 - 白名单需自行校验,框架不内置检查。常见做法是提前过滤:
$cb = input('callback'); if (!in_array($cb, ['list', 'detail'])) { abort(400); } - TP6 推荐改用 CORS + Fetch/AJAX,JSONP 仅保留在 legacy 接口里;如果必须用,建议把白名单逻辑封装成公共方法,避免每个接口重复写
in_array - 别漏掉大小写:JavaScript 函数名区分大小写,
GetList和getlist是两个不同值
绕过白名单的典型错误操作
很多人以为加个正则就能防住,结果反而失效。最常踩的坑是过度信任客户端输入或混淆了处理时机。
- 在
initialize()里用input('callback')取值后存到属性,但后续json()->jsonp()仍会重新读取 GET 参数,导致白名单校验失效 - 用
str_replace过滤点号、括号等字符,但攻击者可用 Unicode 编码绕过(如cal%u006cback) - 把白名单写死在接口方法里,但忘了某些前端 SDK 会自动添加随机后缀(如
jQuery123456789_1234567890),这类应统一用前缀匹配而非全等 - 在 Nginx 层用
if ($args ~* callback=)重写参数,但 ThinkPHP 的input()读的是原始 QUERY_STRING,Nginx 重写未必生效,且容易误杀正常请求
真正安全的做法只有两个:严格白名单 + 提前 abort。任何“过滤”“替换”“转义”都不可靠,因为 JSONP 的执行上下文是 script 标签,只要能拼出合法 JS 语句,就可能被运行。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!










