问ChatGPT:
你详细解释下try_files 指令?
ChatGPT回答:
当Nginx处理客户端请求时,try_files
指令用于按照指定的顺序尝试查找文件,并在找到匹配的文件时返回内容,或者在没有找到匹配文件时执行备用操作。通常,try_files
指令用于静态文件服务器的配置,以确定如何响应用户请求。
try_files
指令的语法如下:
Copy code
try_files file ... uri;
-
file ...
:这是一个或多个文件路径,用空格分隔。Nginx会按照指定的顺序尝试查找这些文件。如果找到了任何一个文件,Nginx将返回该文件的内容。 -
uri
:这是备用操作,当找不到匹配的文件时执行。通常,这是一个URL路径,可以是相对路径(相对于服务器的根目录)或绝对路径。
try_files
指令的执行流程如下:
-
Nginx会按照指定的顺序尝试查找
file
路径中列出的文件。如果找到匹配的文件,它会返回该文件的内容。 -
如果在
file
路径中的文件都没有找到,则 Nginx 会执行备用操作,即根据uri
进行处理。
一般情况下,try_files
的常见用法是:
nginxCopy code
try_files $uri $uri/ /fallback-path;
在这个例子中:
$uri
:Nginx会尝试查找与请求路径相对应的文件。$uri/
:Nginx会尝试查找与请求路径加上斜杠对应的目录(通常用于查找目录下的默认文件)。/fallback-path
:如果前面的查找都没有匹配成功,Nginx会执行备用操作,使用这个路径来处理。
几个重点
file...
这里是说 try_files 中间的参数都是file,不是路径,这个指令的目的是找到文件
location /abc {
root /data/www/team/;
try_files 1.html 2.html @qwe;
}和
location /abc {
alias /data/www/team/;
try_files 1.html 2.html @qwe;
}区别
root
和 alias
在 Nginx 配置中的用法非常相似,但它们在处理请求时有一些区别。下面是两个配置之间的主要区别:
使用 root
:
location /abc {
root /data/www/team/;
try_files 1.html 2.html /forward_uri;
}
- 当使用
root
指令时,Nginx会将请求的 URI 路径直接映射到文件系统路径,然后根据文件系统路径查找文件。所以,请求/abc/1.html
会在/data/www/team/abc/1.html
路径下查找文件。 - 如果 URI 路径中包含的目录结构与文件系统路径一致,
root
通常能够直接工作
使用 alias
location /abc {
alias /data/www/team/;
try_files 1.html 2.html /forward_uri;
}
- 当使用
alias
指令时,Nginx将根据alias
指令提供的路径映射请求的 URI 路径。所以,请求/abc/1.html
会在/data/www/team/1.html
路径下查找文件。 alias
可以更精确地控制 URI 路径与文件系统路径之间的映射,而不受 URI 路径中的目录结构的影响。
总之,两者的区别在于文件系统路径的构建方式。root
会将请求的 URI 路径直接添加到根路径下,而 alias
则会替换 URI 路径的部分,并根据 alias
指令提供的路径构建文件系统路径。根据你的需求,你可以选择适合的指令来处理文件系统路径的映射。
再来理解$uri 和 $uri/
$uri是一种变量,以为着所有上述1.html这类的文件以及1.html/index.html的文件,1.html/ 有点奇怪,换一种 geoip 和 geoip/index.html ,有没有这种没有后缀名的文件?答案是肯定的
这种文件是存在的,当然它也可以是一个文件夹 geoip/index.html ,所以这些类型$uri 和 $uri/都能包含,甚至包括它们的子目录都是这样找文件,要么找到文件返回去,要么找到该目录下的index.html返回去
/forward_uri
这个估计绕了很多人,因为上面有个alias path,我们自然以为还是在这个路径下,其实是相对域名的,因此如果你的vue-router 你想放在某个路径下,例如/admin 前缀下,那么再上面file...都找不到的时候,跳转的是
https://xxx.example.com/admin/index.html,如果你写成了/index.html,则跳转的是
https://xxx.example.com/index.html 这个自然是找不到的路径,因此报404
所以你要配置为
A项目
http://xxx.example.com/A
B项目
http://xxx.example.com/B
nginx的配置
location ^~/A {
alias /XX/A;//此处为A的路径
index index.html;
try_files $uri $uri/ /A/index.html;
}
location ^~/B {
alias /XX/B;//此处为B的路径
index index.html;
try_files $uri $uri/ /B/index.html;
}
这样vue-router,history二级路由/admin/dashboard(找不到 dashboard 也找不到 dashboard/index.html)才能被正确 跳转到/admin/index.html 这个文件,该文件已经被浏览器缓存了,所以浏览器不会再次发起请求,而是直接运行本地的 index.html,index.html 中的 js 会获取 URL 栏中的 uri,然后做路由的匹配,实现界面的变化;
js运行起来后,才能识别/admin/dashbord这个路由
vue端为什么要配置 `publicPath:"/admin"` ,因为默认载入的分片 js路径是相对根路径 /的,仍然还是去 /js/2ea8e923cad.js 找,全路径就是
https://xxx.example.com//js/2ea8e923cad.js 这个路径 Nginx 不识别,直接返回 404,实际路径应该是
https://xxx.example.com//admin/js/2ea8e923cad.js 那怎么让 vue 打包出来的代码,能够自动在引入的分片 js 前都自动加上前缀 /admin呢?
那就是要在 vue.config.js 中配置 publicPath:"/admin"即可,这就是 publicPath 的意义。