ThinkPHP前端接口对接核心是确保数据格式、状态码、跨域、鉴权四者一致;常见报错如404(路由未显式声明)、405(方法不匹配)、net::ERR_CONNECTION_REFUSED(服务未启动)、Unexpected token(JSON响应前有额外输出)。

ThinkPHP 前端接口对接,核心不是“能不能通”,而是“通了之后数据格式、状态码、跨域、鉴权是否一致”。多数报错(如 404、405、net::ERR_CONNECTION_REFUSED、Unexpected token )都源于这四点没对齐。
路由配置必须显式声明 API 路径,不能依赖默认模块规则
ThinkPHP 5/6 默认路由不自动暴露控制器方法,Route::get('api/user', 'UserController@index') 这类写法必须存在,且路径要和前端请求的 URL 完全一致(包括前缀、大小写、斜杠结尾)。常见错误:
- 前端请求
/api/user,但路由只写了user,漏了api/前缀 - 用了模块分组(如
api模块),却没在路由中指定模块名:Route::get('user', 'api/UserController@index')缺少api/模块前缀会导致 404 - ThinkPHP 6 的
route/app.php和route/route.php文件作用不同,混淆使用导致路由未加载
json() 返回必须是纯数组,不能混用 echo 或模板输出
API 接口返回必须是标准 JSON,任何额外输出(空格、BOM、var_dump、echo、模板 display())都会让响应体变成非法 JSON。典型错误现象是前端收到 Unexpected token < in JSON at position 0 —— 实际返回的是 HTML(比如 ThinkPHP 错误页或模板内容)。
- 控制器方法里只允许调用
return json([...]),禁止echo json_encode(...)(会丢失 Content-Type) - 确保没有开启调试模式下的 HTML 错误页干扰:生产环境务必关闭
app_debug = false - 若需调试,用
Log::info($data)记日志,而不是dump()或print_r()
CORS 中间件必须拦截所有 API 请求,且响应头不能被 Nginx/Apache 覆盖
小程序、Vue 等前端若与 ThinkPHP 不同源(协议、域名、端口任一不同),就必须处理跨域。仅在控制器开头写 header("Access-Control-Allow-Origin: *") 是不可靠的 —— 它可能被后续框架逻辑覆盖,或被 Web 服务器拒绝发送。
前端设计与 UI/UX 全方位优化专家。覆盖视觉层次、排版系统、色彩理论、响应式布局、交互体验、动画动效、无障碍访问、性能优化八大维度,帮助开发者将普通页面升级为高品质产品级界面。前端设计与 UI/UX 全方位优化专家。覆盖视觉层次、排版系统、色彩理论、响应式布局、交互体验、动画动效、无障碍访问、性能优化八大维度,帮助开发者将普通页面升级为高品质产品级界面。
立即学习“PHP免费学习笔记(深入)”;
- 推荐方式:用中间件统一处理,例如
app/middleware/CrossDomain.php,并在app/middleware.php中绑定到api路由分组 - 关键头必须完整:
Access-Control-Allow-Origin、Access-Control-Allow-Methods、Access-Control-Allow-Headers、Access-Control-Allow-Credentials(若需带 Cookie) - Nginx 配置中若已有
add_header,会覆盖 PHP 设置的 header,此时必须删掉 Nginx 的相关配置,或改用always_set_header
Token 验证必须放在中间件,不能只在控制器里手写 if 判断
登录后返回 Token,后续请求携带 Authorization: Bearer xxx,这个验证逻辑如果散落在每个控制器方法里,极易遗漏、重复、出错。而且无法拦截 OPTIONS 预检请求 —— 导致跨域失败。
- 必须封装为中间件(如
CheckToken),注册在 API 路由分组下 - 中间件内要明确处理:
Authorization头解析、JWT 解码(或查数据库)、过期校验、throw new HttpException(401, 'token invalid') - 注意:OPTIONS 请求不会进入控制器,但会进中间件 —— 所以中间件里要跳过 OPTIONS,否则预检直接 401
最常被忽略的其实是响应体结构一致性:前端约定好只认 code/msg/data 字段,但某个接口忘了包一层就直接 return json($user),前端解析时就会崩。这类问题不会报错,但数据永远拿不到 —— 它安静地错着。


















