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;'
还有我的 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
我正在使用 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;'
还有我的 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