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

使用FETCH请求时出现FastCGI PHP文件找不到问题排查

NextJS+PHP+Nginx架构下Fetch请求API报"Primary script unknown"错误修复

问题描述

我正在做一个学习Docker的项目,采用NextJS+PHP后端+Nginx架构。目前项目已能正常运行:通过浏览器地址栏访问API时,会返回预期的错误页面,Nginx无报错。但使用FETCH请求API时,PHP-FPM容器返回“file not found”,Nginx则报错“FastCGI sent in stderr: "Primary script unknown" while reading response header from upstream”。

站点Nginx配置如下:

upstream next_app {
  # NextJS running app port
  server nextapp:3000;
}

upstream php_fpm {
  # PHP FPM server URI and port
  server phpapp:9000;
}

server {
  listen 80 default_server;

  server_name _;

  server_tokens off;

  error_log /var/log/nginx/error.log;
  access_log /var/log/nginx/access.log;

  location ~ ^/api {
      root /var/www;
      try_files /www/index.php =404;

      include fastcgi_params;
      fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

      fastcgi_pass php_fpm;
  }

  # proxy pass for NodeJS app
  proxy_http_version 1.1;

  proxy_set_header Host                $http_host;
  proxy_set_header X-Real-IP           $remote_addr;
  proxy_set_header X-Forwarded-For     $proxy_add_x_forwarded_for;
  proxy_set_header X-Forwarded-Proto   $scheme;
  proxy_set_header Host                $host;
  proxy_cache_bypass $http_upgrade;

  location / {
    proxy_pass http://next_app;
  }
}

设计思路是让所有以/api开头的请求都走PHP接口,怀疑是NextJS的Fetch机制导致问题,但未找到解决办法,请问该如何修复?

问题根源

浏览器地址栏访问和Fetch请求的差异在于请求路径的处理:直接在浏览器访问/api/xxx时,Nginx匹配location ~ ^/api后,try_files直接指定了/www/index.php,刚好命中文件;但Fetch请求时,NextJS的路径处理可能导致$fastcgi_script_name变成/api/xxx,结合root /var/www,SCRIPT_FILENAME就变成了/var/www/api/xxx,而这个文件在PHP容器中不存在,因此触发"Primary script unknown"错误。

另外原有try_files写法存在问题:/www/index.php是绝对路径,结合root /var/www,实际会查找/var/www/www/index.php,这大概率不是PHP文件的实际位置。

修复步骤

1. 修正Nginx的API location配置

假设PHP入口文件index.php在PHP容器的/var/www目录下(所有/api请求通过该入口做路由),调整location ~ ^/api块:

location ~ ^/api {
    root /var/www;
    # 所有/api请求转发到index.php,保留查询参数用于路由解析
    try_files $uri $uri/ /index.php?$query_string;

    include fastcgi_params;
    # 指定正确的PHP入口文件路径
    fastcgi_param SCRIPT_FILENAME $document_root/index.php;
    # 传递原始请求路径给PHP,用于路由处理
    fastcgi_param PATH_INFO $fastcgi_path_info;
    fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;

    fastcgi_pass php_fpm;
}

如果需要每个/api子路径对应单独的PHP文件,需确保$document_root$fastcgi_script_name指向PHP容器中实际存在的文件,同时匹配Nginx的root配置。

2. 验证PHP容器的文件路径

进入PHP-FPM容器,确认PHP文件的实际位置:

docker exec -it phpapp bash
ls -l /var/www

确保index.php(或对应API文件)存在于/var/www目录,否则调整Nginx的root参数指向PHP文件的实际根目录。

3. 检查NextJS的Fetch请求路径

确保NextJS中Fetch请求使用绝对路径(如/api/xxx),避免相对路径或带域名的路径,确保Nginx能匹配到location ~ ^/api规则。

关键说明

  • try_files按顺序检查文件/目录,不存在则转发到指定入口,确保所有/api请求都由PHP入口处理路由。
  • SCRIPT_FILENAME必须精确指向PHP容器中存在的文件,否则PHP-FPM会返回"file not found"。
  • 开发环境下需注意NextJS开发服务器的代理配置,确保代理指向Nginx的API路径,而非直接请求PHP容器。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 18:54:20