ThinkPHP 5.1+ 中 paginate() 返回 JSONP 跨域失效的主因是:未正确转数组即调用 jsonp()、手动添加 CORS 头干扰 JSONP 执行、callback 参数名不匹配、PHP 错误信息污染响应体;应先 $page->toArray() 或 with() 组装结构化数据,显式获取 callback 名,禁用 display_errors 并 try/catch 兜底。

ThinkPHP 5.1+ 中 paginate() 返回 JSONP 时跨域失效
直接调用 paginate() 后用 jsonp() 输出,浏览器仍报跨域错误——因为 ThinkPHP 默认的 jsonp() 响应不带 Access-Control-Allow-Origin 头,且 JSONP 本身绕过 CORS,但服务端若同时设置了 CORS 头反而可能干扰 JSONP 的 script 标签执行逻辑。
- JSONP 请求本质是动态插入
<script src="url?callback=fn"></script>,服务端只需返回fn({...})格式字符串,**不能**加 CORS 响应头(尤其是Access-Control-Allow-Credentials: true会直接让浏览器拒绝执行) - ThinkPHP 的
json()/jsonp()方法默认不设置任何跨域头,但如果你在中间件或控制器里手动加了header('Access-Control-Allow-Origin: *'),会导致 JSONP 脚本被浏览器拦截(尤其在带 cookie 的场景下) - 正确做法:只确保输出纯 JSONP 内容,不混用 CORS
jsonp() 前必须先调用 with() 或手动组装数据
ThinkPHP 的 paginate() 返回的是 Paginator 对象,它不能直接被 jsonp() 序列化(会丢失分页元信息或触发 __toString 报错)。必须先转成数组,并显式保留 data、last_page、current_page 等字段。
- 错误写法:
return jsonp($list->paginate(10));→ 报错或返回空 - 正确写法:先
$page = $list->paginate(10);,再jsonp($page->toArray()) - 更稳妥:用
with()预载数据并统一结构:return jsonp(['code' => 0, 'data' => $page->items(), 'page' => $page->currentPage(), 'pages' => $page->lastPage(), 'total' => $page->total()]);
callback 参数名不是固定 callback,需从请求中显式读取
ThinkPHP 的 jsonp() 方法默认只认 callback 查询参数,但前端 JS 库(如 jQuery.ajax)可能发 cb、jsoncallback 或自定义名。硬编码会导致 404 或返回普通 JSON。
使用 JSON Schema 验证 JSON 数据,从示例 JSON 生成 schema,并将其转换为 TypeScript 接口、Python 数据类或 Markdown 文档。
- 检查实际请求 URL,例如:
/api/list?page=1&cb=jQuery123456789 - 手动提取 callback 名:
$callback = input('cb', input('callback', 'jsonpCallback')); - 再调用:
return jsonp($data, $callback); - 注意:如果用了路由变量或参数绑定,确保
cb没被路由规则过滤掉(比如['ext'=>'html']可能导致 query string 解析异常)
生产环境禁用 display_errors,否则 JSONP 返回 PHP 错误信息会破坏格式
一旦分页查询出错(如数据库断连、字段不存在),PHP 错误信息以文本形式混在 jsonp() 响应里,前端 script 执行时直接 SyntaxError —— 这类问题在线上极难定位,因为浏览器只报“unexpected token <”或“unexpected token ”。
立即学习“PHP免费学习笔记(深入)”;
- 确认 php.ini 中
display_errors = Off,或在入口文件开头加ini_set('display_errors', '0'); - 开启日志:
Log::write($e->getMessage(), 'error');,不要把异常堆栈吐给 JSONP - 兜底处理:对
paginate()做 try/catch,返回标准错误结构:['code'=>500, 'msg'=>'分页失败', 'data'=>[]],再传给jsonp()


















