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

Laravel 7中OPTIONS预检500错误无法被Handler.php拦截,如何追踪堆栈?

排查PHP中OPTIONS预检请求500错误的日志拦截方法

以下是几种能直接捕获OPTIONS请求错误的实用方法:

  • 在入口文件最顶部添加全局错误捕获
    预检请求可能在框架中间件或Handler执行前就触发了致命错误,因此直接在项目入口(如index.php)最顶部添加错误捕获逻辑,能覆盖框架启动前的错误:

    <?php
    // 开启全量错误报告并指定日志路径
    error_reporting(E_ALL);
    ini_set('display_errors', 1);
    ini_set('log_errors', 1);
    ini_set('error_log', '/var/www/html/php_errors.log'); // 替换为可写的日志路径
    
    // 捕获致命错误
    register_shutdown_function(function() {
        $fatalError = error_get_last();
        if ($fatalError && in_array($fatalError['type'], [E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR])) {
            $errorMsg = "OPTIONS请求致命错误: {$fatalError['message']} | 文件: {$fatalError['file']} | 行号: {$fatalError['line']}";
            error_log($errorMsg);
            // 手动返回CORS头避免浏览器重复报错
            header("Access-Control-Allow-Origin: *");
            header("Access-Control-Allow-Methods: GET, POST, OPTIONS");
            header("Access-Control-Allow-Headers: Content-Type");
            http_response_code(500);
        }
    });
    
    // 捕获非致命错误
    set_error_handler(function($errno, $errstr, $errfile, $errline) {
        $errorMsg = "OPTIONS请求错误: [$errno] $errstr | 文件: $errfile | 行号: $errline";
        error_log($errorMsg);
        return true;
    });
    
    // 捕获未处理的异常
    set_exception_handler(function($exception) {
        $errorMsg = "OPTIONS请求异常: {$exception->getMessage()} | 文件: {$exception->getFile()} | 行号: {$exception->getLine()}";
        error_log($errorMsg);
        error_log($exception->getTraceAsString());
        // 返回CORS头
        header("Access-Control-Allow-Origin: *");
        header("Access-Control-Allow-Methods: GET, POST, OPTIONS");
        header("Access-Control-Allow-Headers: Content-Type");
        http_response_code(500);
    });
    
    // 后续加载框架初始化代码
    require __DIR__.'/vendor/autoload.php';
    // ... 其他框架启动逻辑
    
  • 直接查看Web服务器日志

    • Apache:检查默认日志路径(如/var/log/apache2/error.log),里面会记录PHP致命错误、权限问题等底层错误。
    • Nginx:查看Nginx错误日志(如/var/log/nginx/error.log),同时确保PHP-FPM日志开启(在php-fpm.conf或pool.d/www.conf中设置error_log = /var/log/php-fpm.log),PHP-FPM日志会详细记录PHP层面的执行错误。
  • 用curl手动模拟OPTIONS请求
    绕过浏览器的CORS限制,直接向目标路由发送OPTIONS请求,查看原始响应内容:

    curl -X OPTIONS -v http://your-domain.com/[[route URL]]
    

    命令输出会显示服务器返回的500响应详情,若返回空白,结合Web服务器日志定位问题。

  • 检查Web服务器对OPTIONS请求的放行配置
    部分服务器可能在请求到达PHP前就拦截了OPTIONS请求,可通过配置放行:

    • Apache(.htaccess):
      <IfModule mod_rewrite.c>
          RewriteEngine On
          RewriteCond %{REQUEST_METHOD} OPTIONS
          RewriteRule ^(.*)$ $1 [R=200,L]
      </IfModule>
      
      Header always set Access-Control-Allow-Origin "*"
      Header always set Access-Control-Allow-Methods "GET, POST, OPTIONS"
      Header always set Access-Control-Allow-Headers "Content-Type"
      
    • Nginx(server块内):
      location / {
          if ($request_method = OPTIONS) {
              add_header Access-Control-Allow-Origin *;
              add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
              add_header Access-Control-Allow-Headers 'Content-Type';
              return 204;
          }
          # 其他路由配置
      }
      

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 22:50:10