You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让PHP返回错误供JS Promise的catch捕获?跨域预检报错解析

问题解答:通过PHP header()让AJAX Promise的catch捕获错误

这个需求是完全可行的!你现在遇到的报错问题,根源是跨域预检请求(OPTIONS)没有正确处理,而不是用header返回错误状态码的思路有问题。

为什么当前代码会报错?

跨域请求时,浏览器会先自动发送一个OPTIONS类型的预检请求,用来确认服务器是否允许后续的实际请求(比如你的GET请求)。你的PHP代码没有专门处理OPTIONS请求,导致预检请求进来后,会执行到业务逻辑判断$_SESSION['user_id'] == 0,返回了500错误状态码——浏览器看到预检请求返回错误,就直接终止了后续流程,根本不会发送实际的GET请求,自然你的Promise catch也不会触发。

解决方案:先处理预检请求,再返回标准HTTP错误码

  1. 优先处理OPTIONS预检请求:在PHP代码最开头添加逻辑,当请求方法是OPTIONS时,直接返回200状态码和必要的CORS头,不要执行后续业务逻辑。
  2. 使用标准HTTP错误状态码:尽量避免自定义像1337这样的状态码,虽然浏览器能识别,但不符合HTTP规范,部分客户端可能处理异常。推荐用400(请求错误)、401(未授权)、403(禁止访问)、500(服务器错误)这类标准码。

修正后的完整PHP代码

<?php
session_start();
$_SESSION['user_id'] = 1;

// 专门处理OPTIONS预检请求
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    header("Access-Control-Allow-Origin: *");
    header("Access-Control-Allow-Credentials: true");
    header("Access-Control-Allow-Methods: GET,HEAD,OPTIONS,POST,PUT");
    header("Access-Control-Allow-Headers: Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers");
    http_response_code(200);
    exit;
}

// 为实际请求设置CORS头
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Credentials: true");
header("Access-Control-Allow-Methods: GET,HEAD,OPTIONS,POST,PUT");
header("Access-Control-Allow-Headers: Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers");

if ($_SESSION['user_id'] == 0) {
    header('Content-Type: application/json');
    print json_encode(["test" => 123]);
} else {
    // 使用标准的403禁止访问状态码
    http_response_code(403);
    header('Content-Type: application/json; charset=UTF-8');
    die(json_encode(array('message' => 'ERROR: User ID is not valid', 'code' => 403)));
}
?>

修正后的JavaScript代码(修复语法错误,优化catch逻辑)

axios.get('loginStatus.php', { crossDomain: true })
  .then(function (response) {
    console.log('Success response:', response);
  })
  .catch(function (error) {
    if (error.response) {
      // 服务器返回了错误响应,可以拿到错误详情
      console.log('Error message:', error.response.data.message);
      console.log('Error status code:', error.response.status);
    } else {
      // 请求发送失败(比如网络问题)
      console.log('Request failed:', error.message);
    }
  });

补充说明

当然,你也可以选择始终返回200状态码,在JSON响应里携带错误标识(比如{ "success": false, "message": "xxx" }),然后在then方法里判断处理。但用HTTP状态码的方式更符合RESTful设计规范,也能让Promise的catch自动捕获错误,代码逻辑更清晰。

内容的提问来源于stack exchange,提问作者Kalreg

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:28:00