Nginx - 根与别名,用于服务单个文件?

Cyc*_*ops 79 nginx

在处理nginx单个文件(例如robots.txt(提示:每次都清除浏览器缓存))多个小时后,我最终采用了两种不同的方式,一种使用alias指令,另一种使用root指令,如下所示:

location /robots.txt { alias /home/www/static/robots.txt; }
location /robots.txt { root /home/www/static/;  }
Run Code Online (Sandbox Code Playgroud)

两者之间有什么功能上的区别吗?还是安全问题?与其他指令有冲突吗?(对于另一个 /static 位置,两者似乎都很好)。或者有什么理由选择一个?

注-我没有使用这两个在同一时间:)而我想每一个,一次一个,两者的工作。我不是在问它们是如何在同一个文件中交互的,而是使用哪个更好。

Ale*_*lex 82

好吧,这两个指令在功能上略有不同,因为在后一种情况下您不使用精确匹配。因此,/robots.txt1111也将匹配您的第二个位置。
location =/robots.txt { root /home/www/static/; }是与您的第一个指令完全等效的功能。


小智 50

是的,有区别:使用“别名”,您可以.. 为另一个文件名设置别名,例如

location /robots.txt { alias /home/www/static/any-filename.txt; }
Run Code Online (Sandbox Code Playgroud)

然而

location /robots.txt { root /home/www/static/; }
Run Code Online (Sandbox Code Playgroud)

强制您将服务器上的文件也命名为 robots.txt。我使用第一个选项,因为我喜欢将服务器上的机器人文件命名为 tld.domain.subdomain-robots.txt;例如

location /robots.txt { alias /home/www/static/ch.notex.static-robots.txt; }
Run Code Online (Sandbox Code Playgroud)


kbo*_*ino 5

我认为值得明确指出 nginx 是对前缀而不是文件本身进行操作。在第一种情况下,

location /robots.txt { alias /home/www/static/robots.txt; }
Run Code Online (Sandbox Code Playgroud)

nginx 将URL 路径中的字符串前缀 替换为,然后将结果用作文件系统路径。表示为伪代码,这将类似于:/robots.txt/home/www/static/robots.txt

if urlPath.startsWith("/robots.txt") {
    fsPath := "/home/www/static/robots.txt" + urlPath.stripPrefix("/robots.txt")
    serveFile(fsPath)
}
Run Code Online (Sandbox Code Playgroud)

So/robots.txt是从/home/www/static/robots.txt因为/robots.txt去除/robots.txt前缀是空字符串,并附加空字符串/home/www/static/robots.txt使其保持不变。但是,/robots.txt1将从/home/www/static/robots.txt1/robots.txt/foobar将从 提供服务/home/www/static/robots.txt/foobar。这些文件可能不存在,导致 nginx 发送 404 响应,而且很可能这robots.txt不是目录,但 nginx 事先不知道,这都是基于字符串前缀而不是看起来是文件的或目录的结尾斜杠的缺失或存在。

而在第二种情况下,

location /robots.txt { root /home/www/static/; }
Run Code Online (Sandbox Code Playgroud)

nginx/home/www/static/在 URL 路径的开头插入字符串,然后将结果用作文件系统路径。在伪代码中,这将类似于:

if urlPath.startsWith("/robots.txt") {
    fsPath := "/home/www/static/" + urlPath
    serveFile(fsPath)
}
Run Code Online (Sandbox Code Playgroud)

这与第一种情况具有完全相同的结果,但原因不同。有没有前缀剥离,但因为每个URI路径必须包含前缀/robots.txt,那么文件系统路径总是先从/home/www/static//robots.txt相当于 /home/www/static/robots.txt

当然,伪代码并不能说明全部情况,例如 nginx 不会盲目使用原始 URL 路径,例如/../../../etc/passwdtry_files指令会更改root/的行为alias,并且对alias可以使用的位置有限制。