1.1 location规则介绍
location是nginx的精华,nginx就是通过拦截到的请求去对配置好的location块(location block)进行
请求代理的。
location是用来具体配置代理路径的,具体格式如下:
1
| location [=|~|~*|^~|@] /uri/ { … }
|
被代理的url去对location后边的字符串(或正则)进行匹配,根据一定的规则选择走哪个location,以
下是匹配规则。
1 2 3 4 5 6 7 8
| 语法规则: location [=|~|~*|^~] /uri/ { … } = 开头表示精确匹配 ^~ 开头表示uri以某个常规字符串开头,理解为匹配 url路径即可。nginx不对url做编码,因此请求 为/static/20%/aa,可以被规则^~ /static/ /aa匹配到(注意是空格)。 ~ 开头表示区分大小写的正则匹配 ~* 开头表示不区分大小写的正则匹配 !~和!~*分别为区分大小写不匹配及不区分大小写不匹配 的正则 / 通用匹配,任何请求都会匹配到
|
1 2 3
| Location优先级: = > ^~ > ~|~*|!~|!~* > / 相同的优先级,匹配与配置文件的配置顺序有关,在上面的优先匹配
|
Localtion的匹配规则,首先匹配 =,其次匹配^~, 其次是按文件中顺序的正则匹配,最后是交给 / 通用
匹配。当有匹配成功时候,停止匹配,按当前匹配规则处理请求。
实例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| location = / { #规则A } location = /login { #规则B } location ^~ /static/ { #规则C } location ~ \.(gif|jpg|png|js|css)$ { #规则D } location ~* \.png$ { #规则E } location !~ \.xhtml$ { #规则F } location !~* \.xhtml$ { #规则G } location / { #规则H }
|
产生效果:
1 2 3 4 5 6 7 8 9 10 11 12
| 访问根目录/, 比如http://localhost/ 将匹配规则A 访问 http://localhost/login 将匹配规则B,http://localhost/register 则匹配规则H 访问 http://localhost/static/a.html 将匹配规则C 访问 http://localhost/a.gif, http://localhost/b.png 将匹配规则D和规则E,但是规则D顺序 优先,规则E不起作用,而 http://localhost/static/c.png 则优先匹配到 规则C 访问 http://localhost/a.PNG 则匹配规则E, 而不会匹配规则D,因为规则E不区分大小写。 访问http://localhost/a.xhtml 不会匹配规则F和规则G,http://localhost/a.XHT ML不会匹配规则G,因为不区分大小写。规则F,规则G属于排除法,符合匹配规则但是不会匹配到,所以想想 看实际应用中哪里会用到。 访问 http://localhost/category/id/1111 则最终匹配到规则H,因为以上规则都不匹配,这个时候 应该是nginx转发请求给后端应用服务器,比如FastCGI(php),tomcat(jsp),nginx作为方向代理 服务器存在。
|
所以实际使用中,通常至少有三个匹配规则定义,如下:
直接匹配网站根,通过域名访问网站首页比较频繁,使用这个会加速处理,官网如是说。
这里是直接转发给后端应用服务器了,也可以是一个静态首页
第一个必选规则
1 2 3
| location = / { proxy_pass http://tomcat:8080/index }
|
第二个必选规则是处理静态文件请求,这是nginx作为http服务器的强项
有两种配置模式,目录匹配或后缀匹配,任选其一或搭配使用
1 2 3 4 5 6
| location ^~ /static/ { root /webroot/static/; } location ~* \.(gif|jpg|jpeg|png|css|js|ico)$ { root /webroot/res/; }
|
第三个规则就是通用规则,用来转发动态请求到后端应用服务器
非静态文件请求就默认是动态请求,自己根据实际把握
毕竟目前的一些框架的流行,带.php,.jsp后缀的情况很少了
1 2 3
| location / { proxy_pass http://tomcat:8080/ }
|
1.2 地址重写原理与实践
1.2.1 地址重写介绍
Rewrite对称URL Rewrite,即URL重写,就是把传入Web的请求重定向到其他URL的过程。
1.URL Rewrite最常见的应用是URL伪静态化,是将动态页面显示为静态页面方式的一种技术。比如 htt
p://www.123.com/news/index.php?id=123 使用URLRewrite 转换后可以显示为 http://www.123.co
m/news/123.html对于追求完美主义的网站设计师,就算是网页的地址也希望看起来尽量简洁明快。理
论上,搜索引擎更喜欢静态页面形式的网页,搜索引擎对静态页面的评分一般要高于动态页面。所以,
UrlRewrite可以让我们网站的网页更容易被搜索引擎所收录。
2.从安全角度上讲,如果在URL中暴露太多的参数,无疑会造成一定量的信息泄漏,可能会被一些黑客
利用,对你的系统造成一定的破坏,所以静态化的URL地址可以给我们带来更高的安全性。
3.实现网站地址跳转,例如用户访问360buy.com,将其跳转到jd.com。例如当用户访问tianyun.com
的80端口时,将其跳转到443端口。
和apache等web服务软件一样,rewrite的组要功能是实现URL地址的重定向。Nginx的rewrite功能需
要PCRE软件的支持,即通过perl兼容正则表达式语句进行规则匹配的。默认参数编译nginx就会支持
rewrite的模块,但是也必须要PCRE的支持
epm -a pcre
rewrite是实现URL重写的关键指令,根据regex(正则表达式)部分内容,重定向到replacement,结
尾是flag标记。
1.2.2 Nginx地址重写语法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| 在匹配过程中可以引用一些Nginx的全局变量 $args 请求中的参数; $document_root 针对当前请求的根路径设置值; $host 请求信息中的"Host",如果请求中没有Host行,则等于设置的服务器名; $limit_rate 对连接速率的限制; $request_method 请求的方法,比如"GET"、"POST"等; $remote_addr 客户端地址; $remote_port 客户端端口号; $remote_user 客户端用户名,认证用; $request_filename 当前请求的文件路径名(带root指定的路径) $request_uri 当前请求的文件路径名(不带root指定的路径 /images/a.jpg) $query_string 与$args相同; $scheme 用的协议,比如http或者是https $server_protocol 请求的协议版本,"HTTP/1.0"或"HTTP/1.1"; $server_addr 服务器地址,如果没有用listen指明服务器地址,使用这个变量将发起一次系统调用以取得地址; $server_name 请求到达的服务器名; $document_uri 与$uri一样,URI地址; $server_port 请求到达的服务器端口号;
|
1.2.3 rewrite语法
rewrite语法格式及参数语法说明如下:
1 2 3 4 5 6 7 8 9 10 11 12 13
| rewrite <regex> <replacement> [flag]; 关键字 正则 替代内容 flag标记
关键字:其中关键字rewrite不能改变 正则:perl兼容正则表达式语句进行规则匹配 替代内容:将正则匹配的内容替换成replacement flag标记:rewrite支持的flag标记
flag标记说明: last #本条规则匹配完成后,继续向下匹配新的location URI规则 break #本条规则匹配完成即终止,不再匹配后面的任何规则 redirect #返回302临时重定向,浏览器地址会显示跳转后的URL地址 permanent #返回301永久重定向,浏览器地址栏会显示跳转后的URL地址
|
区别:
redirect 和 permanent区别则是返回的不同方式的重定向,对于客户端来说一般状态下是没有区别的。而对于搜
索引擎,相对来说301的重定向更加友好,如果我们把一个地址采用301跳转方式跳转的话,搜索引擎会把老地
址的相关信息带到新地址,同时在搜索引擎索引库中彻底废弃掉原先的老地址。使用302重定向时,搜索引擎
(特别是google)有时会查看跳转前后哪个网址更直观,然后决定显示哪个,如果它觉的跳转前的URL更好的话,
也许地址栏不会更改,那么很有可能出现URL劫持的现像。在做URI重写时,有时会发现URI中含有相关参数,
如果需要将这些参数保存下来,并且在重写过程中重新引用,可以用到 () 和 $N 的方式来解决。
1.2.4 rewrite企业应用场景
Nginx的rewrite功能在企业里应用非常广泛:
可以调整用户浏览的URL,看起来更规范,合乎开发及产品人员的需求。
为了让搜索引擎搜录网站内容及用户体验更好,企业会将动态URL地址伪装成静态地址提供服务。
网址换新域名后,让旧的访问跳转到新的域名上。例如,访问京东的360buy.com会跳转到jd.com
根据特殊变量、目录、客户端的信息进行URL调整等
1.2.5 地址重写实例
实例1:如果访问不存在的任意网页都重定向到错误页面
1 2 3 4 5 6 7
| location / { root html; index index.html index.htm; if (!-f $request_filename) { rewrite /.* /err.html permanent; (permanent表示永久的重定向到这个页 面) }
|
实例2:为某个目录定义别名,用户访问的路径其实并不存在,而是将其转发到另外一个页面
1 2 3 4 5 6
| location / { root html; index index.html ; rewrite ^/forum/(.*) /bbs/$1 last ; ...... }
|
实例3:实现域名跳转
1 2 3 4 5 6 7 8 9 10 11
| server { listen 80; server_name web.uplook.com; 如果访问web.uplook.com则跳转到www.uplook.com rewrite ^/.* http://www.uplook.com/$1 last; #charset koi8-r; #access_log logs/host.access.log main; location / { root html; index index.html ; }
|
1.2.6 Nginx地址重写企业运用场景
实例一:
1 2 3 4 5
| #http://www.blog.com/abc/a/1.html ==> http://www.blog.com/ccc/bbb/2.html location /abc { rewrite .* /ccc/bbb/2.html permanent; #return 301 /ccc/bbb/2.html; }
|
实例二:
1 2 3 4
| #http://www.blog.com/2015/ccc/bbb/2.html ==> http://www.blog.com/2014/ccc/bbb/2.html location /2015 { rewrite ^/2015/(.*)$ /2014/$1 permanent; }
|
实例三:
1 2 3 4 5
| #http://www.360buy.com/aaa/1.html ==> http://jd.com if ( $host ~* 360buy.com ) { rewrite .* http://jd.com permanent; } 注意:配置host
|
实例四:
1 2 3 4
| #http://www.360buy.com/ccc/1.html ==> http://jd.com/ccc/1.html if ( $host ~* 360buy.com ) { rewrite .* http://jd.com$request_uri permanent; }
|
实例五:
1 2 3 4 5 6 7 8
| 在访问目录后添加/ (如果目录后已有/,则不加/) #http://www.blog.com/ccc/abc #$1: /ccc/ab #$2: c #http://$host$1$2/ if (-d $request_filename) { rewrite ^(.*)([^/])$ http://$host$1$2/ permanent; http://www.360buy123.com/ccc/abc/ }
|
实例六:
1 2 3 4
| #http://www.blog.com/login/blog.html ==> http://www.blog.com/reg/login.php?user=blog location /login { rewrite ^/login/(.*)\.html$ /reg/login.php?user=$1 permanent; }
|
实例七:
1 2 3 4
| #http://www.blog.com/uplook/11-22-33.html ==> http://www.blog.com/uplook/11/22/33.html location /uplook { rewrite ^/uplook/([0-9]+)-([0-9]+)-([0-9]+)\.html$ /uplook/$1/$2/$3.html permanent; }
|
实例八:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| set 指令是用于定义一个变量,并且赋值。应用于server,location,if环境。 #http://alice.blog.com ==> http://www.blog.com/alice #http://jack.blog.com ==> http://www.blog.com/jack [root@root html]# mkdir jack alice [root@root html]# echo jack.... > jack/index.html [root@root html]# echo alice... > alice/index.html
a. DNS实现泛解析 *.blog.com IN A 网站IP b. nginx Rewrite if ($host ~* "^www.blog.com$" ) { break; } if ($host ~* "^(.*)\.blog\.com$" ) { set $user $1; rewrite .* http://www.blog.com/$user permanent; }
|
实例九:
1 2 3 4 5 6 7 8 9 10 11 12 13
| 80 ======> 443 访问80端口跳转到443端口 server { listen 80; server_name www.blog.com blog.com; return 301 https://www.blog.com$request_uri; } server { listen 443 ssl; server_name www.blog.com; ssl on; ssl_certificate /usr/local/nginx/conf/cert.pem; ssl_certificate_key /usr/local/nginx/conf/cert.key;: }
|