我需要通过我在 8080
的应用服务器提供我的应用程序,并从一个目录中提供我的静态文件,而无需接触应用程序服务器。我拥有的 nginx 配置是这样的......
# app server on port 8080
# nginx listens on port 8123
server {
listen 8123;
access_log off;
location /static/ {
# root /var/www/app/static/;
alias /var/www/app/static/;
autoindex off;
}
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
现在,有了这个配置,一切正常。请注意,root
指令已被注释掉。
如果我激活 root
并停用 alias
- 它会停止工作。但是,当我从 root
中删除尾随 /static/
时,它又开始工作了。
有人可以解释发生了什么。还请清楚详细地解释 root
和 alias
之间的区别及其用途。
root
和 alias
指令之间有一个非常重要的区别。这种差异存在于处理 root
或 alias
中指定的路径的方式上。
root
位置部分附加到根部分
最终路径 = 根 + 位置
alias
位置部分被别名部分替换
最终路径 = 别名
为了显示:
假设我们有配置
location /static/ {
root /var/www/app/static/;
autoindex off;
}
在这种情况下,Nginx 将派生的最终路径将是
/var/www/app/static/static
这将返回 404
,因为 static/
中没有 static/
这是因为位置部分附加到 root
中指定的路径。因此,对于 root
,正确的方法是
location /static/ {
root /var/www/app/;
autoindex off;
}
另一方面,使用 alias
,位置部分会丢弃。所以对于配置
location /static/ {
alias /var/www/app/static/;
autoindex off; ↑
} |
pay attention to this trailing slash
最终路径将正确形成为
/var/www/app/static
在某种程度上,这是有道理的。 alias
只是让您定义一个新路径来表示现有的“真实”路径。位置部分是新路径,因此它被替换为真实路径。将其视为符号链接。
另一方面,根不是一条新路径,它包含一些必须与其他信息进行比较才能形成最终路径的信息。因此,位置部分被使用,而不是被丢弃。
别名中尾部斜杠的情况
对于每个 Nginx documentation 是否必须使用尾部斜杠,没有明确的指导方针,但这里和其他地方的人们的共同观察似乎表明它是强制性的。
更多的地方已经讨论过这个问题,虽然不是最终的。
https://serverfault.com/questions/375602/why-is-my-nginx-alias-not-working
正如@treecoder 所说
在 root 指令的情况下,完整路径将附加到包含位置部分的根,而在别名指令的情况下,仅将不包括位置部分的路径部分附加到别名。
一张图片胜过千言万语
root
:
https://i.stack.imgur.com/vCgqh.png
alias
:
https://i.stack.imgur.com/Oahx0.png
在您的情况下,您可以使用 root
指令,因为 location
指令的 $uri
部分与最后一个 root
指令部分相同。
Nginx 文档也给出了建议:当 location 与指令值的最后一部分匹配时: location /images/ { alias /data/w3/images/;最好使用 root 指令: location /images/ { root /data/w3; }
root
指令会将 $uri
附加到路径中。
只是对@good_computer 非常有用的答案的快速补充,我想用文件夹替换 URL 的根目录,但前提是它与包含静态文件的子文件夹匹配(我想将其保留为路径的一部分)。
例如,如果请求的文件在 /app/js
或 /app/css
中,则在 /app/location/public/[that folder]
中查找。
我使用正则表达式让它工作。
location ~ ^/app/((images/|stylesheets/|javascripts/).*)$ {
alias /home/user/sites/app/public/$1;
access_log off;
expires max;
}
alias
用于替换请求路径中的位置部分路径 (LPP),而 root
用于添加到请求路径的前面。
它们是将请求路径映射到最终文件路径的两种方式。
alias
只能在位置块中使用,它会覆盖外部的 root
。
alias
和 root
不能在位置块中一起使用。
server {
server_name xyz.com;
root /home/ubuntu/project_folder/;
client_max_body_size 10M;
access_log /var/log/nginx/project.access.log;
error_log /var/log/nginx/project.error.log;
location /static {
index index.html;
}
location /media {
alias /home/ubuntu/project/media/;
}
}
服务器块在 nginx 上运行静态页面。
虽然不需要我的回答,但我认为有必要添加这个,root
和 alias
在使用正则表达式时的工作方式不同。
location ~ /static/my.png$ {
alias /var/www/static/;
access_log off;
expires max;
}
在这种情况下,正则表达式匹配不会添加别名,nginx 将仅搜索 /var/www/static/
而不是 /var/www/static/my.png
。您必须使用正则表达式捕获。
location ~ /static/my.png$ {
root /var/www;
access_log off;
expires max;
}
在这种情况下,匹配的 url 将添加 root,nginx 将搜索 /var/www/static/my.png
。
换句话说,保持简短:在 root
的情况下,指定的位置参数是 文件系统的路径和 URI 的一部分。另一方面,对于 alias
指令,location 语句的参数是 URI only 的一部分
因此,alias
是一个不同的名称,它将某个 URI 映射到文件系统中的某个路径,而 root
将 location 参数附加到作为 root
指令参数给出的根路径。
log_format scripts '$document_root | $uri | > $request';
放入http
部分,将access_log /var/log/nginx/scripts.log scripts;
放入 nginx 配置的server
部分。nginx: [emerg] invalid number of arguments in "alias" directive
,并且服务器在重新启动期间停机。