Nginx教程(4)-Rewrite

proxy_pass 只能将请求进行转发,而rewrite的功能就多喽,如

  • 可以调整用户浏览的 URL,看起来更规范,合乎开发及产品人员的需求。
  • 为了让搜索引擎搜录网站内容及用户体验更好,企业会将动态 URL 地址伪装成静态地址提供服务。
  • 网址换新域名后,让旧的访问跳转到新的域名上。例如,访问京东的 360buy.com 会跳转到 jd.com
  • 根据特殊变量、目录、客户端的信息进行 URL 调整等

rewrite语法:
server {
  rewrite 规则 定向路径 重写类型;
}

  • 规则:可以是字符串或者正则来表示想匹配的目标 url
  • 定向路径:表示匹配到规则后要定向的路径,如果规则里有正则,则可以使用$index 来表示正则里的捕获分组
  • 重写类型:last、break、redirect、permanent
server {
	listen 80;
	server_name localhost;
	rewrite /break.html /index.html break;
}

rewrite可以直接作用于server中,访问 /break.html 的时候,页面内容重写到 /index.html 中
重写类型:

  • last :表示完成 rewrite,浏览器地址栏 URL 地址不变
  • break;本条规则匹配完成后,终止匹配,不再匹配后面的规则,浏览器地址栏 URL
    地址不变
  • redirect:返回 302 临时重定向,浏览器地址会显示跳转后的 URL 地址
  • permanent:返回 301 永久重定向,浏览器地址栏会显示跳转后的 URL 地址

last和break的区别:

  • last 一般写在 server 和 if 中,而 break 一般使用在 location 中
  • last 不终止重写后的 url 匹配,即新的 url 会再从 server 走一遍匹配流程,而 break 终止重写后的匹配
server {
	location / {
		rewrite /last/ /q.html last;
		rewrite /break/ /q.html break;
	}
	location = /q.html {
		return 400;
	}
}

访问/last/时重写到/q.html,然后使用新的 uri 再匹配,正好匹配到 locatoin =/q.html 然后返回了 400

访问/break 时重写到/q.html,由于返回了 break,则直接停止了

rewrite 可以写在server中也可以写在location中,先判断server中的,然后再判断location中的。

if判断

在Nginx中可以使用if做一些简单的逻辑判断

if (表达式) {
}

表达式判断:
1、正则表达式匹配:
==:等值比较;
~:与指定正则表达式模式匹配时返回“真”,判断匹配与否时区分字符大小写;
~:与指定正则表达式模式匹配时返回“真”,判断匹配与否时不区分字符大小写;
!~:与指定正则表达式模式不匹配时返回“真”,判断匹配与否时区分字符大小写;
!~
:与指定正则表达式模式不匹配时返回“真”,判断匹配与否时不区分字符大小写;

2、文件及目录匹配判断:
-f, !-f:判断指定的路径是否为存在且为文件;
-d, !-d:判断指定的路径是否为存在且为目录;
-e, !-e:判断指定的路径是否存在,文件或目录均可;
-x, !-x:判断指定路径的文件是否存在且可执行;

3、部分正则表达式可以在圆括号内"()",其值可以通过后面的变量$1到$9来访问:
rewrite ^/b/(.).html /play.php?video=$1 last;#其中$1就表示引用前面匹配的(.)里面的内容。

Nginx可以通过内置变量获取url信息,如:

问链接是:http://localhost:8080/test1/test2/test.jsp
$host:localhost
$server_port:8080
$request_uri:http://localhost:8080/test1/test2/test.jsp
$document_uri:/test1/test2/test.jsp
更内置变量见附件

server {
	
	# 如果 host 不是 a.test.com,则 301 到 a.test.com 中
	if ( $host != "a.test.com" ){
	 rewrite ^/(.*)$ https://a.test.com/$1 permanent;
	}
	# 如果请求类型不是 POST 则返回 405
	if ($request_method = POST) {
	 return 405;
	}

	location / {
		# 自定义变量
		set $flag 0;
		if ($host != "a.test.com" ) {
		    set $flag "${flag}1";
		}
		if ($flag = "01") {
		    return 500;
		}
	}
}

if不仅可以作用于server中,也可以作用于location中

server {
	location / {
		if ($host = "a.test.com"){
			rewrite ^/(.*)$ http://b.test.com/$1 permanent;
		}
		# $1 表示正则表达式(.*).html$匹配的结果(.*)
		rewrite ^/shop/list/cat-(.*).html$ /ecps-portal/listcat?catId=$1 break;
		rewrite ^/shop/(.*)$ /ecps-portal/shop/$1.jsp last;
		# 请求将会转发到 b.test.com
		proxy_pass http://b.test.com;
	}
}

如果if不满足,会继续执行

附录

内置的全局变量
argsargs :这个变量等于请求行中的参数,同query_string
$content_length : 请求头中的 Content-length 字段。
$content_type : 请求头中的 Content-Type 字段。
$document_root : 当前请求在 root 指令中指定的值。
$host : 请求主机头字段,否则为服务器名称。
$http_user_agent : 客户端 agent 信息
$http_cookie : 客户端 cookie 信息
$limit_rate : 这个变量可以限制连接速率。
$request_method : 客户端请求的动作,通常为 GET 或 POST。
$remote_addr : 客户端的 IP 地址。
$remote_port : 客户端的端口。
$remote_user : 已经经过 Auth Basic Module 验证的用户名。
$request_filename : 当前请求的文件路径,由 root 或 alias 指令与 URI 请求生成。
$scheme : HTTP 方法(如 http,https)。
$server_protocol : 请求使用的协议,通常是 HTTP/1.0 或 HTTP/1.1。
$server_addr : 服务器地址,在完成一次系统调用后可以确定这个值。
$server_name : 服务器名称。
$server_port : 请求到达服务器的端口号。
$request_uri : 包含请求参数的原始 URI,不包含主机名,
如:”/foo/bar.php?arg=baz”。
uriURIuri : 不带请求参数的当前 URI,uri 不包含主机名,如”/foo/bar.html”。
documenturidocument_uri : 与uri 相同。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章