NGINX returns 页面重新加载时出现 404 错误(Ember 应用程序)

NGINX returns 404 error on page reload (Ember app)

我正在使用 nginx 在同一域上提供登录页面、SPA (Ember) 和 Rails 后端。一切似乎都很好,除了当我刷新一些 SPA 路由时,例如 https://server_name.ru/app/login NGINX returns 404 错误 /home/aborovkov/apps/frontend/dist/login" failed。如何解决这个问题?

server {
        root /home/aborovkov/apps/landing;
        index index.html index.htm index.nginx-debian.html;
        try_files $uri $uri/ /index.html?/$request_uri;
        add_header Cache-Control "no-store, no-cache, must-revalidate, max-age=0";
        add_header Pragma "no-cache";

        server_name server_name.ru www.server_name.ru;
        access_log /etc/nginx/server_name.access.log;
        error_log /etc/nginx/server_name.error.log;

        location /app {
          alias  /home/aborovkov/apps/frontend/dist;
          index index.html index.htm index.nginx-debian.html
          try_files $uri $uri/ /index.html?/$request_uri;
          add_header Cache-Control "no-store, no-cache, must-revalidate, max-age=0";
          add_header Pragma "no-cache";
        }

        location /api/ {
          root /home/aborovkov/apps/api/current/public;
          proxy_pass  http://localhost:3000;

          passenger_enabled on;
          passenger_app_env production;
          client_max_body_size 100m;
        }

        listen [::]:443 ssl ipv6only=on; # managed by Certbot
        listen 443 ssl; # managed by Certbot
        ssl_certificate /etc/letsencrypt/live/server_name.ru/fullchain.pem; # managed by Certbot
        ssl_certificate_key /etc/letsencrypt/live/server_name.ru/privkey.pem; # managed by Certbot
        include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
        ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}

 server {
    if ($host = www.server_name.ru) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


    if ($host = server_name.ru) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


        listen 80;
        listen [::]:80;

        server_name server_name.ru www.server_name.ru;
    return 404; # managed by Certbot
}

您需要在 /app 块上进行更简单的 try_files 声明,以将所有 URL 转发到您的静态资产。 这是我使用的:

server {
    listen       ${NGINX_LISTENING_PORT};
    server_name  localhost;

    gzip on;
    gzip_disable "msie6";

    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 6;
    gzip_buffers 16 8k;
    gzip_http_version 1.1;
    gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/vnd+api.json;

    location / {
        root   /emberclear;

        try_files $uri /index.html;
    }
}

来源:https://github.com/NullVoxPopuli/emberclear/blob/master/packages/frontend/scripts/docker/nginx.conf

然后通过 nginx 启动脚本解释以替换变量:

#!/usr/bin/env sh

export NGINX_LISTENING_PORT=${PORT:-80}
export VARS_TO_REPLACE='$NGINX_LISTENING_PORT'

if [ "$NGINX_CONF_DIR" = "" ]
then
    NGINX_CONF_DIR=/etc/nginx/conf.d
fi

envsubst "$VARS_TO_REPLACE" < $NGINX_CONF_DIR/default.conf.template > $NGINX_CONF_DIR/default.conf
cat $NGINX_CONF_DIR/default.conf

echo "Starting emberclear..."
nginx -g 'daemon off;'

酱:https://github.com/NullVoxPopuli/emberclear/blob/master/packages/frontend/scripts/docker/run-nginx.sh

还有我的 dockerfile,如果你想要一个完全可运行的东西:

FROM nginx:alpine

COPY dist/ /emberclear
COPY scripts/docker/run-nginx.sh /usr/local/bin
COPY scripts/docker/nginx.conf etc/nginx/conf.d/default.conf.template

EXPOSE 4201
CMD ["/usr/local/bin/run-nginx.sh"]

来源:https://github.com/NullVoxPopuli/emberclear/blob/master/packages/frontend/Dockerfile.release