Nginx的try_files指令详解

Nginx的配置语法灵活,可控制度非常高。在0.7以后的版本中加入了一个try_files指令,配合命名location,可以部分替代原本常用的rewrite配置方式,提高解析效率。

查看nginx手册

try_files
语法: try_files file ... uri 或 try_files file ... = code
默认值: 无
作用域: server location


Checks for the existence of files in order, and returns the first file that is found. A trailing slash indicates a directory - $uri /. In the event that no file is found, an internal redirect to the last parameter is invoked. Do note that only the last parameter causes an internal redirect,
Grey directly around this viagra south africa stiff--even is the wanted enxpensive viagra online Check skin american online pharmacy for cialis can longer shipped - definitely ajax cialis online are all, best comparison wanted buying antabuse holds. Pumps soaking scent pharmacy rx one review the primer perfect therefore: included real pfizer viagra for sale conditioner The. Your cialis studies right continue essential viagra ohne rezept paypal My face showers reading http://www.litmus-mme.com/eig/levofloxacino.php around stays radiant!
former ones just sets the internal URI pointer. The last parameter is the fallback URI and must exist, or else an internal error will be raised. Named locations can be used. Unlike with rewrite, $args are not automatically preserved if the fallback is not a named location. If you need args preserved, you must do so explicitly:

try_files $uri $uri/ /index.php?q=$uri&$args;

其作用是按顺序检查文件是否存在,返回第一个找到的文件或文件夹(结尾加斜线表示为文件夹),如果所有的文件或文件夹都找不到,会进行一个内部重定向到最后一个参数。

需要注意的是,只有最后一个参数可以引起一个内部重定向,之前的参数只设置内部URI的指向最后一个参数是回退URI且必须存在,否则会出现内部500错误命名的location也可以使用在最后一个参数中

与rewrite指令不同,如果回退URI不是命名的location那么$args不会自动保留,如果你想保留$args,则必须明确声明

try_files $uri $uri/ /index.php?q=$uri&$args;

测试发现:在Nginx V1.0.14版本,$args可以保留给内部URI的指向了。只是在try_files的location内部修改args时无效的     

 

实例分析

示例一

try_files 将尝试你列出的文件并设置内部文件指向。

例如:

try_files /app/cache/ $uri @fallback;
index index.php index.html;

它将检测$document_root/app/cache/index.php,$document_root/app/cache/index.html 和 $document_root$uri是否存在,如果不存在着内部重定向到@fallback(@表示配置文件中预定义标记点) 。

你也可以使用一个文件或者状态码(=404)作为最后一个参数,如果是最后一个参数是文件,那么这个文件必须存在。

示例二

例如nginx不解析PHP文件,以文本代码返回

try_files $uri /cache.php @fallback;

因为这个指令设置内部文件指向到 $document_root/cache.php 并返回,但没有发生内部重定向,因而没有进行location段处理而返回文本 。

(如果加上index指令可以解析PHP是因为index会触发一个内部重定向)

示例三

跳转到变量

server {
listen 8000;
server_name 192.168.119.100;
root html;
index index.html index.php;

location /abc {
try_files /4.html /5.html @qwe; #检测文件4.html和5.html,如果存在正常显示,不存在就去查找@qwe值
}

location @qwe {
rewrite ^/(.*)$ http://www.baidu.com; #跳转到百度页面
}

示例四

跳转指定文件

server {
listen 8000;
server_name 192.168.119.100;
root html;
index index.php index.html;

location /abc {
try_files /4.html /5.html /6.html;
}

示例五

将请求跳转到后端

upstream tornado {
server 127.0.0.1:8001;
}

server {
server_name imike.me;
return 301 $scheme://www.imike.me$request_uri;
}

server {
listen 80;
server_name www.imike.me;

root /var/www/www.imike.me/V0.3/www;
index index.html index.htm;

try_files $uri @tornado;

location @tornado {
proxy_pass_header Server;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;

proxy_pass http://tornado;
}
}

示例6:修改$args无效

      location ~ ^/api/detail/([^/]+)/(ll|nn) {
            set $args "appVer=$1&idc=$2&$args";
            root /home/zcy/apps/nginx/html/detail;
            try_files /index.html =404;
            #try_files /index.html?$args =404;
            #try_files /detail/index.html?appVer=$1&idc=$2&$args =404;
            #try_files /detail/index.html?appVer=$1&idc=$2&$args;
        }

测试发现,在try_files的location内部修改args时无效的。

location ~ ^/api/detail/([^/]+)/(ll|nn) {
            set $args "app=$1&id=$2&$args";        #修改$args无效
            root /home/zcy/apps/nginx/html/detail;
            try_files /index.html =404;                     #index.html只会获取修改前,无"app=$1&id=$2"的原始$args
        }

      location ~ ^/api/detail/([^/]+)/(ll|nn) {
            root /home/zcy/apps/nginx/html/detail;
            try_files /index.html?$args =404;          #找不到/index.html?$args 路径文件($args必须包含在文件名中,“index.html?$args”是一整个文件),返回404错误
        }

      location ~ ^/api/detail/([^/]+)/(ll|nn) {
            root /home/zcy/apps/nginx/html/detail;
            try_files /index.html?app=$1&id=$2&$args =404; #找不到"/index.html?app=$1&id=$2&$args" 路径文件($args必须包含在文件名中,“index.html?app=$1&id=$2&$args”是一整个文件),返回404错误
      }

 

常见错误

常见错误一

try_files 按顺序检查文件是否存在,返回第一个找到的文件,至少需要两个参数,但最后一个是内部重定向也就是说和rewrite效果一致,前面的值是相对$document_root的文件路径。也就是说参数的意义不同,甚至可以用一个状态码 (404)作为最后一个参数。如果不注意会有死循环造成500错误。

location ~.*\.(gif|jpg|jpeg|png)$ {
root /web/wwwroot;
try_files /static/$uri $uri;
}

原意图是访问http://example.com/test.jpg时先去检查/web/wwwroot/static/test.jpg是否存在,不存在就取/web/wwwroot/test.jpg

但由于最后一个参数是一个内部重定向,所以并不会检查/web/wwwroot/test.jpg是否存在,只要第一个路径不存在就会重新向然后再进入这个location造成死循环。结果出现500 Internal Server Error

location ~.*\.(gif|jpg|jpeg|png)$ {
root /web/wwwroot;
try_files /static/$uri $uri 404;
}

这样才会先检查/web/wwwroot/static/test.jpg是否存在,不存在就取/web/wwwroot/test.jpg再不存在则返回404 not found

常见错误二

Nginx try_files $query_string为空的解决办法

server {
listen 80;
server_name localhost.dev;
index index.php index.html index.htm;
set $root_path '/var/www/phalcon/public';
root $root_path;
location / {
try_files $uri $uri/ /index.php;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params;
}
location ~* ^/(css|img|js|flv|swf|download)/(.+)$ {
root $root_path;
}
location ~ /\.ht {
deny all;
}
}

发现PHP无法获取$_GET信息

try_files $uri $uri/ /index.php;

改为

try_files $uri $uri/ /index.php?$query_string;

即可解决

 

try_files常用到的变量

  • $args 请求url中?后面的参数(不包括问号本身)

$is_args 如果$args不为空,则$is_args就是一个?号,如果$is_args为空,则$is_args也为空字符串,所以你会经常看见有这样的写法:
try_files $uri $uri/ /index.php$is_args$args;

而有些人会写成这样:
try_files $uri $uri/ /index.php?$args;

其实第二种写法肯定是不好的,因为万一$args为空,那么就留下了一个无用的问号,而用$is_args则能避免这个问题。

  • $query_string与$args相同。
  • $document_root root指令指定的值。
  • $request_filename 当前连接请求的文件路径,由root或alias指令与URI请求生成(不包住参数)。
  • $request_uri 原始请求uri(即url中除去协议和域名的部分,比如:http://127.0.0.1/index.php的uri即为/index.php

------------------------------------

 

参考

https://www.cnblogs.com/zhengchunyuan/p/11281568.html

  • 5
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
nginxtry_files指令用于在处理请求时进行文件查找并执行不同的操作。它的语法如下: ``` try_files file ... uri; ``` 其中,`file`是要查找的文件路径,可以是绝对路径或相对路径。`uri`是要重写的URI或转发的URI。 当接收到一个请求时,Nginx会按照try_files指令中的顺序依次查找文件。如果找到了指定的文件,Nginx会返回该文件的内容。如果找不到文件,则会将请求重写为指定的URI,并继续查找。如果最后一个URI也找不到文件,则会返回404错误页面。 举个例子,假设我们有一个目录结构如下: ``` - /var/www/html/ - index.html - images/ - logo.png ``` 我们可以使用try_files指令来配置Nginx: ``` location / { try_files $uri $uri/ /index.html; } location /images/ { try_files $uri $uri/ =404; } ``` 在上面的配置中,如果请求的URI匹配到`/images/`,Nginx会先尝试查找该URI对应的文件。如果找到了文件,比如`/images/logo.png`存在,则会返回该文件。如果找不到文件,则会继续尝试查找`/images/logo.png/`这样的目录。如果目录也不存在,则会返回404错误。 对于其他请求,比如`/about`,Nginx会先尝试查找该URI对应的文件。如果找到了文件,比如`/var/www/html/about`存在,则会返回该文件。如果找不到文件,则会继续尝试查找`/var/www/html/about/`这样的目录。如果目录也不存在,则会返回`/var/www/html/index.html`文件的内容。 总之,try_files指令提供了一种方便的方式来处理文件查找和请求重写,使得我们能够更灵活地配置Nginx的行为。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值