需在handler.php的render()中精准识别api请求并分路径处理:非api走默认html页,api则用response()->json()返回标准json,显式设content-type头,并适配业务异常、验证异常等各类错误。

ThinkPHP6 要实现「异常统一接管 + 页面请求走自定义 HTML 错误页、AJAX 请求强制返回 JSON」,核心不在加功能,而在精准识别请求类型并分路径处理。默认的 render() 方法对非 AJAX 请求仍会输出 HTML,必须主动拦截判断。
区分 API 与普通页面请求
不能只看 $request->isAjax(),它在某些代理或跨域场景下可能失效。更可靠的方式是结合路由特征或中间件标记:
- 检查 URL 是否以
/api/、/v1/等前缀开头:str_starts_with($request->url(), '/api/') - 若项目已为 API 路由注册了
api中间件,可用$request->hasMiddleware('api') - 也可在全局中间件中提前设置标识:
$request->withAttr('is_api', true),后续直接读取
重写 render() 返回结构化 JSON
在 app\common\exception\Handler.php 的 render() 方法中,先判断是否为 API 场景,再构造响应:
用于端到端视频本地化流程的轻量编排器,路由至四个专注子技能——/wjs-transcribing-audio、/wjs-translating-subtitles...
- 不是 API 请求:直接
return parent::render($request, $e),走默认 HTML 错误页流程 - 是 API 请求:用
response()->json()构建标准格式,例如:['code' => $e->getCode() ?: 500, 'msg' => $e->getMessage(), 'data' => []] - 务必显式设置头信息:
->header('Content-Type', 'application/json'),避免框架自动识别出错 - 不要用
json()辅助函数——它在异常上下文中可能因前置输出失败;response()->json()更可控
业务异常需继承并携带 code 字段
想让 throw new BusinessException('用户未登录', 1001) 正确带出业务码,得确保异常类本身支持:
- 自定义异常类(如
app\common\exception\BusinessException)应继承\Exception,并提供$errorCode属性和构造参数 -
render()中通过instanceof BusinessException判断,取$e->errorCode而非$e->getCode()(后者默认是 PHP 异常级别码) - 避免在异常类里重写
getCode()方法,易与 HTTP 状态码混淆;统一用自定义字段传递业务错误码
验证失败等框架异常也要适配 JSON
比如表单验证失败抛出 ValidateException,默认仍跳转或返回 HTML。需在 render() 中单独捕获:
if ($e instanceof ValidateException) { return response()->json(['code' => 422, 'msg' => $e->getError(), 'data' => []]); }- 同理处理
RouteNotFoundException(404)、HttpException(含 401/403/500)等,按需映射业务码 - 调试模式下可保留原始堆栈(
env('app_debug')为 true 时调用父类 render),生产环境一律走 JSON
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!










