ThinkPHP 的 jsonp() 默认仅识别 callback 参数,需 URL 显式携带 ?callback=xxx,否则返回空响应;支持自定义参数名需显式传参或全局配置 default_jsonp_handler;手动拼接时须校验回调名安全、设正确 header;分页数据须先转数组再传入;生产环境须关闭 display_errors。

ThinkPHP 的 jsonp() 默认只读 callback 参数
前端发请求时,URL 必须带 ?callback=xxx,否则 jsonp() 会返回空响应(不报错、不提示)。它不会自动 fallback 到 cb 或 jsoncallback,也不会从 POST 或请求头读取。常见现象是:接口返回纯 JSON 字符串,浏览器控制台报 Uncaught SyntaxError: Unexpected token {——本质是没触发 JSONP 包裹逻辑。
如何支持自定义回调参数名(如 cb)
有两种方式,推荐后者:
- 调用时显式传参:
jsonp($data, ['callback' => 'cb']) - 全局配置(在
app.php中):'default_jsonp_handler' => 'cb'
注意:如果用了路由变量或后缀规则(如 'ext' => 'html'),要确认 cb 没被路由解析器过滤掉;Nginx 缓存策略也需把该参数纳入 cache_key,否则不同 cb 值可能命中同一缓存。
手动提取并校验回调名更可控
绕过 jsonp() 助手函数,自己拼接 JSONP 响应时,必须手动处理回调名安全问题:
立即学习“PHP免费学习笔记(深入)”;
- 用
input('cb', input('callback', 'jsonpCallback'))优先读cb,再 fallback 到callback - 用
htmlspecialchars()或白名单正则(如/^[a-zA-Z_][a-zA-Z0-9_\.]*$/)过滤非法字符,防 XSS - 长度建议限制在 32 字以内,避免超长函数名导致 JS 解析失败
- 输出前必须设 header:
header('Content-Type: application/javascript; charset=utf-8');
漏掉任意一项,都可能导致前端报 callback is not defined 或直接执行失败。
分页数据不能直接传给 jsonp()
$list->paginate(10) 返回的是 Paginator 对象,不是数组,jsonp() 无法正确序列化它——轻则丢失分页字段,重则触发 __toString() 报错或返回空。
- 错误写法:
return jsonp($list->paginate(10)); - 正确做法:先转数组,再传入,例如
jsonp($page->toArray()) - 更推荐结构化输出:
jsonp(['code' => 0, 'data' => $page->items(), 'page' => $page->currentPage(), 'total' => $page->total()])
生产环境务必关掉 display_errors,否则 PHP 错误信息会混在 JSONP 响应体开头,直接破坏 JS 语法。



















