在0.7以后的版本中加入了一个try_files指令,配合命名location,可以部分替代原本常用的rewrite配置方式,提高解析效率。
1、try_files指令介绍
语法:try_files file … uri(格式1) 或 try_files file … = code(格式2)
默认值:无
作用域:server location
解释说明:
按指定的file顺序查找存在的文件,并使用第一个找到的文件进行请求处理;
查找路径是按照给定的root或alias为根路径来查找的;
如果给出的file都没有匹配到,则会进行一个内部重定向到最后一个参数给定的uri,就是新的location匹配;
只有最后一个参数可以引起一个内部重定向,之前的参数只设置内部URI的指向;
最后一个参数是回退URI且必须存在,否则会出现内部500错误;
如果是(格式2),若最后一个参数是 = 404 ,若给出的file都没有匹配到,则最后返回404的响应码。
2、举例说明
例1:
root 后面的参数是前端vue项目贷吗安装目录;
try_files 负责扫描内部目录然后再进行内部重定向;
expires 是nginx控制缓存的一种方式,7d=7天。
location / {
root /home/nx/dist;
try_files $uri $uri/ /index.php?$query_string
expires 7d;
}
当用户请求 http://localhost/example 时,这里的 $uri 就是 /example,try_files 会到硬盘里尝试找这个文件;
如果存在名为 /$root/example(其中 $root 是项目代码安装目录)的文件,就直接把这个文件的内容发送给用户;
显然,目录中没有叫 example 的文件;
然后就看 $uri/,增加了一个 /,也就是看有没有名为 /$root/example/ 的目录;
又找不到,就会 fall back 到 try_files 的最后一个选项 /index.php,发起一个内部 “子请求”,也就是相当于 nginx 发起一个 HTTP 请求到 http://localhost/index.php。
例2:
location / {
try_files /app/cache/ $uri @fallback;
index index.php index.html;
}
location @fallback {
rewrite ^/(.*)$ http://www.baidu.com # 跳转到百度
}
它将检测$document_root/app/cache/index.php,$document_root/app/cache/index.html 和 $document_root$uri是否存在,如果不存在着内部重定向到 @fallback。
@表示配置文件中预定义标记点,如上所示(@fallback)。
你也可以使用一个文件或者状态码(=404)作为最后一个参数,如果是最后一个参数是文件,那么这个文件必须存在。
3、我遇到的问题
小编通过nginx启动vue以后,我们在访问页面的时候只能访问默认页面和通过项目内跳转其他页面,如果刷新就会404。如图:
关于单页面,刷新404问题,如vue + nginx的配置, vue路由必须先加载 index.html 或者XX.js 才能识别到路由,故直接刷新页面会出现404。
这时候最好到做法,是使用try_files 进行尝试,如果获取不到资源,加载index.html 再利用 rewrite的 last参数,保持路由路径不变,从而实现刷新页面。
但需要注意:此种解决方法需要 vue和nginx部署在同一台服务器上,这样try_files才能在服务器硬盘上找到index.html文件。
原来的nginx配置:
location / {
root /home/vue/dist;
index index.html index.htm index.jsp;
}
修改后的nginx配置:
将默认的index注释掉,换成了try_files,它会去扫描内部目录然后再进行内部重定向,规则上面介绍过了。
location / {
root /home/nx/dist;
#index index.html index.htm index.jsp;
try_files $uri $uri/ /index.html;
expires 7d;
}
列如在宝塔里:
#REWRITE-START URL重写规则引用,修改后将导致面板设置的伪静态规则失效
include /www/server/panel/vhost/rewrite/你的目录;
#REWRITE-END
location / {
root /www/wwwroot/你的目录/;
try_files $uri $uri/ /index.html;
expires 7d;
}