Nginx 正在提供默认内容而不是我的内容
Nginx is serving the default content instead of my content
我在 Ubuntu 16.04.2 LTS
上有一个 nginx version: nginx/1.10.3 (Ubuntu)
运行。
我使用 nginx
来提供静态文件,由 webpack
生成的包,但这无关紧要。
我要实现的是:
example.com
我想发球 /home/bundles/main/index.html
。我可以做到。
在 projects.example.com/project_1
我想服务 /home/bundles/project_1/index.html
。
在 projects.example.com/project_2
我想服务 /home/bundles/project_2/index.html
。
最后两个,我做不到。当我转到 projects.example.com/project_1
或 projects.example.com/project_2
时,我会看到默认的 nginx 页面。
为了让事情更混乱 /etc/nginx/sites-enabled/default
被完全注释掉了。
此外,如果在 projects.example.com
的 location
块中我将 project_1
替换为 /
,我将获得该特定项目,但随后我将无法为对方服务。
下面,我将向您展示我的 nginx 配置
server {
listen 80;
server_name example.com;
location / {
root /home/bundles/main;
try_files $uri /index.html;
}
if ($scheme != "https") {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
server_name example.com;
location / {
root /home/bundles/main;
try_files $uri /index.html;
}
ssl_certificate ...
ssl_certificate_key ...
}
server {
listen 80;
server_name projects.example.com;
location /project_1 {
root /home/bundles/project_1;
try_files $uri /index.html;
}
location /project_2 {
root /home/bundles/project_2;
try_files $uri /index.html;
}
if ($scheme != "https") {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
server_name projects.example.com;
location /project_1 {
root /home/bundles/project_1;
try_files $uri /index.html;
}
location /project_2 {
root /home/bundles/project_2;
try_files $uri /index.html;
}
ssl_certificate ...
ssl_certificate_key ...
}
感谢您的帮助!
编辑
我的回答
我找到的解决方案是将 root
更改为 alias
。
server {
listen 80;
server_name example.com;
location / {
root /home/bundles/main;
try_files $uri /index.html;
}
if ($scheme != "https") {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
server_name example.com;
location / {
root /home/bundles/main;
try_files $uri /index.html;
}
ssl_certificate ...
ssl_certificate_key ...
}
server {
listen 80;
server_name projects.example.com;
location /project_1 {
alias /home/bundles/project_1;
index index.html;
}
location /project_2 {
alias /home/bundles/project_2;
index index.html;
}
if ($scheme != "https") {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
server_name projects.example.com;
location /project_1 {
alias /home/bundles/project_1;
index index.html;
}
location /project_2 {
alias /home/bundles/project_2;
index index.html;
}
ssl_certificate ...
ssl_certificate_key ...
}
解决方案基于这两个答案。第一个 answer showing how to solve the problem and the second answer 解释了为什么 alias
有效而 root
无效。
引用@treecoder
In case of the root directive, full path is appended to the root including the location part, whereas in case of the alias directive, only the portion of the path NOT including the location part is appended to the alias.
在我的特殊情况下,这将像这样翻译;
使用 root
,nginx
尝试访问的路径将是 /home/bundles/project_1/project_1
。
使用 alias
它访问正确的路径,/home/bundles/project_1
。
返回一级,例如,说:
root /home/bundles/
也不是真正的选择。那是因为我的项目实际上并没有被称为project_1
和project_2
。实际结构与此更相似。
在 /bundles
中,我有目录 project_a
和 project_b
。我想将 project_1
路由到 project_a
目录,将 project_2
路由到 project_b
目录。
这就是我使用 alias
的原因。
希望对您有所帮助。
你有:
location /project_1 {
root /home/bundles/project_1;
try_files $uri /index.html;
}
因此 root
仅针对以 /project_1
开头的 URI 定义。对于任何其他 URI,将使用默认 root
。
如果您提供 URI /project_1/
(尾随 /
),假设 default index
directive 有效,nginx
应该 return 您的/project_1/index.html
内容。
但是,未找到 URI /project_1
- 因此 /index.html
改为 returned。 URI /index.html
不以 /project_1
开头,因此使用默认根。
如果您希望 URI /project_1
按预期工作,并且默认操作转到项目的 index.html
文件,请更改 try_files
指令。
location /project_1 {
root /home/bundles/project_1;
try_files $uri $uri/ /project_1/index.html;
}
有关更多信息,请参阅 this document。
由于两个项目共享一个共同的根,您可以简化如下:
server {
listen 80;
server_name projects.example.com;
root /home/bundles
index index.html;
location /project_1 {
try_files $uri $uri/ /project_1/index.html;
}
location /project_2 {
try_files $uri $uri/ /project_2/index.html;
}
location / {
deny all;
}
}
我添加了 index
指令以避免依赖默认值(这是相同的),并添加了 location
块来拒绝访问项目以外的区域。
我遇到了同样的问题......结果对我来说,默认站点“超越”了我想要的辅助站点并提供默认文件......它允许 IP6 请求,而我的新站点没有。
这是我的例子 access.log:
::1 - - [05/Sep/2020:15:05:16 -0600] "GET / HTTP/1.1" 200 40 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36"
注意到 ::1
位了吗?这是我猜我的浏览器默认的 IP6 请求。所以我只是确保通过更改在我的站点配置文件中为相关站点启用本地 IP6 请求:
listen 80;
server_name example.local;
至:
listen 80;
listen [::]:80;
server_name example.local;
就是这样。
我在 Ubuntu 16.04.2 LTS
上有一个 nginx version: nginx/1.10.3 (Ubuntu)
运行。
我使用 nginx
来提供静态文件,由 webpack
生成的包,但这无关紧要。
我要实现的是:
example.com
我想发球 /home/bundles/main/index.html
。我可以做到。
在 projects.example.com/project_1
我想服务 /home/bundles/project_1/index.html
。
在 projects.example.com/project_2
我想服务 /home/bundles/project_2/index.html
。
最后两个,我做不到。当我转到 projects.example.com/project_1
或 projects.example.com/project_2
时,我会看到默认的 nginx 页面。
为了让事情更混乱 /etc/nginx/sites-enabled/default
被完全注释掉了。
此外,如果在 projects.example.com
的 location
块中我将 project_1
替换为 /
,我将获得该特定项目,但随后我将无法为对方服务。
下面,我将向您展示我的 nginx 配置
server {
listen 80;
server_name example.com;
location / {
root /home/bundles/main;
try_files $uri /index.html;
}
if ($scheme != "https") {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
server_name example.com;
location / {
root /home/bundles/main;
try_files $uri /index.html;
}
ssl_certificate ...
ssl_certificate_key ...
}
server {
listen 80;
server_name projects.example.com;
location /project_1 {
root /home/bundles/project_1;
try_files $uri /index.html;
}
location /project_2 {
root /home/bundles/project_2;
try_files $uri /index.html;
}
if ($scheme != "https") {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
server_name projects.example.com;
location /project_1 {
root /home/bundles/project_1;
try_files $uri /index.html;
}
location /project_2 {
root /home/bundles/project_2;
try_files $uri /index.html;
}
ssl_certificate ...
ssl_certificate_key ...
}
感谢您的帮助!
编辑
我的回答
我找到的解决方案是将 root
更改为 alias
。
server {
listen 80;
server_name example.com;
location / {
root /home/bundles/main;
try_files $uri /index.html;
}
if ($scheme != "https") {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
server_name example.com;
location / {
root /home/bundles/main;
try_files $uri /index.html;
}
ssl_certificate ...
ssl_certificate_key ...
}
server {
listen 80;
server_name projects.example.com;
location /project_1 {
alias /home/bundles/project_1;
index index.html;
}
location /project_2 {
alias /home/bundles/project_2;
index index.html;
}
if ($scheme != "https") {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
server_name projects.example.com;
location /project_1 {
alias /home/bundles/project_1;
index index.html;
}
location /project_2 {
alias /home/bundles/project_2;
index index.html;
}
ssl_certificate ...
ssl_certificate_key ...
}
解决方案基于这两个答案。第一个 answer showing how to solve the problem and the second answer 解释了为什么 alias
有效而 root
无效。
引用@treecoder
In case of the root directive, full path is appended to the root including the location part, whereas in case of the alias directive, only the portion of the path NOT including the location part is appended to the alias.
在我的特殊情况下,这将像这样翻译;
使用 root
,nginx
尝试访问的路径将是 /home/bundles/project_1/project_1
。
使用 alias
它访问正确的路径,/home/bundles/project_1
。
返回一级,例如,说:
root /home/bundles/
也不是真正的选择。那是因为我的项目实际上并没有被称为project_1
和project_2
。实际结构与此更相似。
在 /bundles
中,我有目录 project_a
和 project_b
。我想将 project_1
路由到 project_a
目录,将 project_2
路由到 project_b
目录。
这就是我使用 alias
的原因。
希望对您有所帮助。
你有:
location /project_1 {
root /home/bundles/project_1;
try_files $uri /index.html;
}
因此 root
仅针对以 /project_1
开头的 URI 定义。对于任何其他 URI,将使用默认 root
。
如果您提供 URI /project_1/
(尾随 /
),假设 default index
directive 有效,nginx
应该 return 您的/project_1/index.html
内容。
但是,未找到 URI /project_1
- 因此 /index.html
改为 returned。 URI /index.html
不以 /project_1
开头,因此使用默认根。
如果您希望 URI /project_1
按预期工作,并且默认操作转到项目的 index.html
文件,请更改 try_files
指令。
location /project_1 {
root /home/bundles/project_1;
try_files $uri $uri/ /project_1/index.html;
}
有关更多信息,请参阅 this document。
由于两个项目共享一个共同的根,您可以简化如下:
server {
listen 80;
server_name projects.example.com;
root /home/bundles
index index.html;
location /project_1 {
try_files $uri $uri/ /project_1/index.html;
}
location /project_2 {
try_files $uri $uri/ /project_2/index.html;
}
location / {
deny all;
}
}
我添加了 index
指令以避免依赖默认值(这是相同的),并添加了 location
块来拒绝访问项目以外的区域。
我遇到了同样的问题......结果对我来说,默认站点“超越”了我想要的辅助站点并提供默认文件......它允许 IP6 请求,而我的新站点没有。
这是我的例子 access.log:
::1 - - [05/Sep/2020:15:05:16 -0600] "GET / HTTP/1.1" 200 40 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36"
注意到 ::1
位了吗?这是我猜我的浏览器默认的 IP6 请求。所以我只是确保通过更改在我的站点配置文件中为相关站点启用本地 IP6 请求:
listen 80;
server_name example.local;
至:
listen 80;
listen [::]:80;
server_name example.local;
就是这样。