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

Nginx try_files未正常工作:自定义域名请求未转发至Node.js服务

问题

我通过Elastic Beanstalk(EB)搭建了一个搭载Nginx和Node.js的实例:

  • 访问EB自带URL(https://www.my-domain-test.xxxxxxxxxx.us-west-2.elasticbeanstalk.com/)时,Nginx能正确将/路径的请求转发给Node.js;
  • 用Route 53别名记录将自定义域名(https://test.my_domain.com)指向该EB URL后,同样请求/路径,Nginx未转发到Node.js,反而返回root目录下的/index.html(删除该文件则返回Nginx默认的index.html)。

通过在配置中添加return 200 "Server info - $host, $uri";调试确认:EB URL的请求能进入location @nodejs {},但自定义域名的请求无法进入,且两者的$uri均为/。

需要排查问题原因并给出修复方案。

当前Nginx配置

user  nginx;
worker_processes  auto;

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

pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}

http {

    port_in_redirect off;
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] ""$request"" '
                      '$status $body_bytes_sent ""$http_referer"" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;

    keepalive_timeout  600;
    proxy_connect_timeout 600;
    proxy_send_timeout 600;
    proxy_read_timeout 600;
    fastcgi_send_timeout 600;
    fastcgi_read_timeout 600;

    log_format healthd '$msec"$uri"'
                       '$status"$request_time"$upstream_response_time"'
                       '$http_x_forwarded_for';

  upstream nodejs {
    server 127.0.0.1:8081;
    keepalive 256;
  }

  server {
    listen 8080;
    client_max_body_size 60M;

    proxy_connect_timeout 600;
    proxy_send_timeout 600;
    proxy_read_timeout 600;
    fastcgi_read_timeout 600;

    root /var/app/current/public;

    if ($time_iso8601 ~ "^(\d{4})-(\d{2})-(\d{2})T(\d{2})") {
        set $year $1;
        set $month $2;
        set $day $3;
        set $hour $4;
    }
    access_log /var/log/nginx/healthd/application.log.$year-$month-$day-$hour healthd;
    access_log  /var/log/nginx/access.log  main;

    location / {
        try_files $uri @nodejs;
        client_max_body_size 60M;

        if ($http_x_forwarded_proto = 'http') {
          add_header Cache-Control "no-store, no-cache, max-age=0, must-revalidate, proxy-revalidate";
          return 301 https://$host$request_uri;
        }

        #redirects if host doesn't start with www, unless it is test subdomain
        set $is_subdomain_redirect  "0";

        if ($host !~* ^www\.) {
          set $is_subdomain_redirect  "1";
        }

        if ($host ~* ^test\.) {
          set $is_subdomain_redirect  "0";
        }

        if ($is_subdomain_redirect ~* "1") {
          add_header Cache-Control "no-store, no-cache, max-age=0, must-revalidate, proxy-revalidate";
          return 301 $http_x_forwarded_proto://www.$host$request_uri;
        }
    }

    location @nodejs {
        proxy_pass  http://nodejs;
        proxy_set_header   Connection "";
        proxy_http_version 1.1;
        proxy_set_header        Host            $host;
        proxy_set_header        X-Real-IP       $remote_addr;
        proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
    }

    gzip on;
    gzip_comp_level 4;
    gzip_types text/plain text/css application/javascript application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/vnd.ms-fontobject application/x-font-ttf font/opentype image/svg+xml image/x-icon;

    location /public {
        alias /var/app/current/public;
    }

  }

}

问题原因

EB会自动生成针对自身域名的专用Nginx配置(独立server块),该配置将/路径直接转发到Node.js;而自定义域名走的是你配置的默认server块,其中:

  • try_files $uri @nodejs的逻辑是先尝试读取$uri对应的文件,不存在则跳转至@nodejs;
  • Nginx默认会自动查找index.html作为目录请求的首页,当/var/app/current/public/index.html存在时,请求/会直接返回该文件,不会触发@nodejs转发。

修复方案

以下两种方式二选一即可:

方式1:精确匹配/路径,强制转发到Node.js

在server块中添加精确匹配/的location块(优先级高于通用location /),确保/请求直接转发到Node.js:

server {
    listen 8080;
    client_max_body_size 60M;
    # ... 保留原有其他配置 ...

    # 新增:精确匹配/路径,强制转发到Node.js
    location = / {
        proxy_pass  http://nodejs;
        proxy_set_header   Connection "";
        proxy_http_version 1.1;
        proxy_set_header        Host            $host;
        proxy_set_header        X-Real-IP       $remote_addr;
        proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
    }

    location / {
        try_files $uri @nodejs;
        # ... 保留原有if等配置 ...
    }

    # ... 保留原有其他配置 ...
}

方式2:禁用Nginx默认的index文件查找

在server块中显式设置index为空,让Nginx处理/请求时不会自动查找index.html,从而触发try_files的fallback逻辑:

server {
    listen 8080;
    client_max_body_size 60M;
    root /var/app/current/public;
    # 新增:禁用默认index文件查找
    index "";

    # ... 保留原有其他配置 ...

    location / {
        try_files $uri @nodejs;
        # ... 保留原有if等配置 ...
    }

    # ... 保留原有其他配置 ...
}

额外说明

  • 方式1更灵活:仅针对/路径生效,其他路径仍保持try_files逻辑(先找静态文件再转发);
  • 方式2全局生效:所有目录请求都会直接转发到Node.js,适合不需要Nginx托管静态首页的场景;
  • 建议统一自定义Nginx配置,避免依赖EB自动生成的规则,确保不同域名的行为一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 23:28:12