Nginx 配置(一)

location

匹配优先级

1、 绝对匹配

2、部分匹配

分为前缀匹配正则匹配,他们两种匹配方式有分为是否区分大小写。

  • ^~ 前缀匹配区分大小写
  • 空修饰符前缀匹配不区分大小写
  • ~正则匹配区分大小写
  • ~*正则匹配不区分大小写

对于前缀匹配之间的匹配顺序比较是根据匹配到的字符数量来定的,匹配到的字符数量越多就越优先。而正则匹配之间的优先级则是以它们定义的先后顺序来决定的,越先定义的优先级越高。

当解析开始时,所有同类的匹配之间先做比较,最后可以得到一个前缀匹配和一个正则匹配的结果(可能只有其中一种),然后再对这两类匹配做一个比较。如果最终的前缀匹配是使用^~修饰符定义的,那么它将优先于「正则匹配」,否则反之。

访问/abcde会返回什么结果呢?

按照上面的逻辑,
前缀匹配有个2个/abc^~ /ab,按照匹配数量来说/abc胜出。
正则匹配只有一个~ a
最后拿~ a/abc比较,由于前缀匹配没有以^~修饰,所以最终结构是匹配到~ a

server_name

server_name 指令来匹配请求头中的 Host 以方便地建立站点。server_name 支持通配符和正则。

重复server_name只会生效第一个,后面无论多少个不会生效。

使用通配符的server_name

使用~开头表示使用正则匹配,~之后不能有空格。

注意:含有{}符号的表达式需要用""引号包含起来。否者会报错eload service nginx... nginx: [emerg] directive "server_name" is not terminated by ";" in xxxxxx

优先级;字符串 > 通配符 > 正则

当访问一个端口却没有任何 server_name 可以匹配的情况。这时候 nginx 会默认使用第一个 listen 这个端口的 server。当然这个默认值也是可以改的,只要在 listen 指令中加入 default 即可。

内部重定向

location 指定不仅可以定义匹配 path 的配置,还可以定义以@开头的内部重定向。
try_files 的本意是检测某个文件是否存在并访问,最终再 fallback 到一个地方。

访问nginx.cc.com/a或者nginx.cc.com/b会重定向到location @php去。

除了 try_files 之外,其实可以把内部重定向也视为一个普通的路由,使用 rewrite 来跳转。

但由于使用了 rewrite,所以丢失了 $uri

最适使用error_page重定向。

rewrite 与 return 的跳转

nginx 配置中如果想触发一个 3xx 重定向通常有两种方式。一种是使用 rewrite,后面接 redirect(302)permanent(301)。另一种是直接使用 return 返回一个 301302 的状态码,并在第二个参数中带上一个 URL,它将自动被设置为响应头中的 Location 参数。

然而这个配置是有问题的!$request_uri参数是请求的原始 URI,也就是包含 $args 的。而 rewrite 指令本身有自带 $args,于是 $args 就被重复加了一次。比如请求http://localhost/?a=1想被 301 到https://localhost/?a=1?a=1

 正确的写法应该是

  或者干脆使用 return

rewrite 入门

使用 break 指令,它可以让 rewrite 不再进入匹配,直接从 root 查找文件。否则这条location将无穷循环,访问出现500错误

同样效果的try_files

if 指令

nginx中的if指令,只是 rewrite 模块的一部分而已,它的使用是很有局限性的。能在 if 块中使用的指令只是 rewrite 模块中的那些和一些 proxy_pass 之类的特殊指。

rewrite 重置 $uri
return 直接响应请求
set 设置变量
if 根据条件处理指令
break 阻止进入其他 location
rewrite_log 配置是否开启 rewrite 日志
uninitialized_variable_warn 配置是否开启变量初始化日志

上面这段配置会报错,因为deny all不属于rewrite模块,而是 access 模块中的指令。

这样写就可以了。

上面说了除了rewirte模块中的指令外,还有一些指令可以使用:
add_headerproxy_passfastcgi_pass

proxy_pass

proxy_pass 默认使用的是 http 1.0,可以通过 proxy_http_version 指令让它使用 http 1.1,以便开启 keepalive 之类的功能。

proxy_pass 不允许设置域名。

这样会报错

我们可以通过proxy_set_header来解决

参考:

https://www.web-tinker.com/
http://nginx.org/en/docs/http/ngx_http_headers_module.html#add_header
http://seanlook.com/2015/05/17/nginx-location-rewrite/
https://www.nginx.com/blog/creating-nginx-rewrite-rules/