一、什么是Rewrite
Rewrite對稱URL Rewrite,即URL重寫,就是把傳入Web的請求重定向到其他URL的過程。
URL Rewrite最常見的應用是URL偽靜態(tài)化,是將動態(tài)頁面顯示為靜態(tài)頁面方式的一種技術。比如http://www.123.com/news/index.php?id=123 使用URLRewrite 轉換后可以顯示為 http://www.123.com/news/123.html對于追求完美主義的網(wǎng)站設計師,就算是網(wǎng)頁的地址也希望看起來盡量簡潔明快。理論上,搜索引擎更喜歡靜態(tài)頁面形式的網(wǎng)頁,搜索引擎對靜態(tài)頁面的評分一般要高于動態(tài)頁面。所以,UrlRewrite可以讓我們網(wǎng)站的網(wǎng)頁更容易被搜索引擎所收錄。
從安全角度上講,如果在URL中暴露太多的參數(shù),無疑會造成一定量的信息泄漏,可能會被一些黑客利用,對你的系統(tǒng)造成一定的破壞,所以靜態(tài)化的URL地址可以給我們帶來更高的安全性。
實現(xiàn)網(wǎng)站地址跳轉,例如用戶訪問360buy.com,將其跳轉到jd.com。例如當用戶訪問test.com的 80 端口時,將其跳轉到 443 端口。
二、Rewrite 相關指令
Nginx Rewrite 相關指令有 if、rewrite、set、return
1. if語句
應用環(huán)境:
server,location
語法:
if (condition) { … }
if 可以支持如下條件判斷匹配符號
~ 正則匹配 (區(qū)分大小寫)
~* 正則匹配 (不區(qū)分大小寫)
!~ 正則不匹配 (區(qū)分大小寫)
!~* 正則不匹配 (不區(qū)分大小寫)
-f 和!-f 用來判斷是否存在文件
-d 和!-d 用來判斷是否存在目錄
-e 和!-e 用來判斷是否存在文件或目錄
-x 和!-x 用來判斷文件是否可執(zhí)行
在匹配過程中可以引用一些Nginx的全局變量
$args 請求中的參數(shù);
$document_root 針對當前請求的根路徑設置值;
$host 請求信息中的"Host",如果請求中沒有Host行,則等于設置的服務器名;
$limit_rate 對連接速率的限制;
$request_method 請求的方法,比如"GET"、"POST"等;
$remote_addr 客戶端地址;
$remote_port 客戶端端口號;
$remote_user 客戶端用戶名,認證用;
$request_filename 當前請求的文件路徑名(帶網(wǎng)站的主目錄/usr/local/nginx/html/images /a.jpg)
$request_uri 當前請求的文件路徑名(不帶網(wǎng)站的主目錄/images/a.jpg)
$query_string 與$args相同;
$scheme 用的協(xié)議,比如http或者是https
$server_protocol 請求的協(xié)議版本,"HTTP/1.0"或"HTTP/1.1";
$server_addr 服務器地址,如果沒有用listen指明服務器地址,使用這個變量將發(fā)起一次系統(tǒng)調用以取得地址(造成資源浪費);
$server_name 請求到達的服務器名;
$document_uri 與$uri一樣,URI地址;
$server_port 請求到達的服務器端口號;
2. Rewrite flag
rewrite 指令根據(jù)表達式來重定向URI,或者修改字符串??梢詰糜?code>server,location,if環(huán)境下,每行 rewrite 指令最后跟一個 flag 標記,支持的 flag 標記有:
last 相當于Apache里的[L]標記,表示完成rewrite。默認為last。
break 本條規(guī)則匹配完成后,終止匹配,不再匹配后面的規(guī)則
redirect 返回302臨時重定向,瀏覽器地址會顯示跳轉后的URL地址
permanent 返回301永久重定向,瀏覽器地址會顯示跳轉后URL地址
redirect 和 permanent 區(qū)別則是返回的不同方式的重定向,對于客戶端來說一般狀態(tài)下是沒有區(qū)別的。而對于搜索引擎,相對來說301的重定向更加友好,如果我們把一個地址采用301跳轉方式跳轉的話,搜索引擎會把老地址的相關信息帶到新地址,同時在搜索引擎索引庫中徹底廢棄掉原先的老地址。使用302重定向時,搜索引擎(特別是google)有時會查看跳轉前后哪個網(wǎng)址更直觀,然后決定顯示哪個,如果它覺的跳轉前的URL更好的話,也許地址欄不會更改。
2.1 Rewrite匹配參考示例
本地解析host文件
在:C:\Windows\System32\drivers\etc\host
添加:192.168.181.128 www.test.com
示例1:
實現(xiàn)訪問 www.test.com/a/1.html 跳轉到 www.test.com/b/2.html
[root@localhost html]# pwd
/usr/share/nginx/html
[root@localhost html]# cat a/1.html
test
[root@localhost html]# cat b/2.html
tiaozhuan chenggong
# 修改配置文件
[root@localhost conf.d]# cat default.conf
server {
listen 80;
server_name www.test.com;
location /a {
root /usr/share/nginx/html;
index 1.html;
rewrite .* /b/2.html permanent;
}
location /b {
root /usr/share/nginx/html;
index 2.html;
}
}
示例2:
實現(xiàn)訪問www.test.com/2020/a/1.html 跳轉到 www.test.com/2018/a/1.html
[root@localhost html]# pwd
/usr/share/nginx/html
[root@localhost html]# cat 2018/a/1.html
2018
[root@localhost html]# cat 2020/a/1.html
2020
# 修改配置文件
[root@localhost conf.d]# cat default.conf
server {
listen 80;
server_name www.test.com;
location /2020/a {
root /usr/share/nginx/html;
index 1.html;
rewrite ^/2020/(.*)$ /2018/$1 permanent;
}
location /2018/a {
root /usr/share/nginx/html;
index 1.html;
}
}
示例3:
實現(xiàn)訪問 www.test.com/a/1.html 跳轉到 jd.com
# 修改配置文件
[root@localhost conf.d]# cat default.conf
server {
listen 80;
server_name www.test.com;
location /a {
root /usr/share/nginx/html;
if ($host ~* test.com) {
rewrite .* jd.com permanent;
}
}
}
示例4:
實現(xiàn)訪問 www.test.com/a/1.html 跳轉到 jd.com/a/1.html
# 修改配置文件
[root@localhost conf.d]# cat default.conf
server {
listen 80;
server_name www.test.com;
location /a {
root /usr/share/nginx/html;
if ( $host ~* test.com ){
rewrite .* http://jd.com$request_uri permanent;
}
}
}
示例5:
在訪問目錄后添加/ (如果目錄后已有/,則不加/)
[root@localhost c]# pwd
/usr/share/nginx/html/a/b/c
# 修改配置文件
[root@localhost conf.d]# cat default.conf
server {
listen 80;
server_name www.test.com;
location /a/b/c {
root /usr/share/nginx/html;
if (-d $request_filename) {
rewrite ^(.*)([^/])$ http://$host$1$2/ permanent;
}
}
}
# $host: www.test.com
# $1: /a/b/
# $2: c
示例6:
訪問www.test.com/login/test.html 跳轉到 www.test.com/reg/login.html?user=test
[root@localhost reg]# pwd
/usr/share/nginx/html/reg
[root@localhost reg]# cat login.html
login
# 修改配置文件
[root@localhost conf.d]# cat default.conf
server {
listen 80;
server_name www.test.com;
location /login {
root /usr/share/nginx/html;
rewrite ^/login/(.*)\.html$ http://$host/reg/login.html?user=$1;
}
location /reg {
root /usr/share/nginx/html;
index login.html;
}
}
示例7:
訪問 www.test.com/test/11-22-33/1.html 跳轉到 www.test.com/test/11/22/33/1.html
[root@localhost 33]# pwd
/usr/share/nginx/html/test/11/22/33
[root@localhost 33]# cat 1.html
hello nginx
# 修改配置文件
[root@localhost conf.d]# cat default.conf
server {
listen 80;
server_name www.test.com;
location /test {
rewrite ^/test/([0-9]+)-([0-9]+)-([0-9]+)(.*)$ /test/$1/$2/$3$4 permanent;
}
location /test/11/22/33 {
root /usr/share/nginx/html;
index 1.html;
}
}
3. set 指令
set 指令是用于定義一個變量,并且賦值
應用環(huán)境:
server,location,if
應用示例:
訪問 alice.test.com 跳轉到 www.test.com/alice
訪問 jack.test.com 跳轉到 www.test.com/jack
# 本地解析host文件
在:C:\Windows\System32\drivers\etc\host
添加:192.168.181.128 www.test.com alice.test.com jack.test.com
#
[root@localhost html]# pwd
/usr/share/nginx/html
[root@localhost html]# cat jack/index.html
jack
[root@localhost html]# cat alice/index.html
alice
# 修改配置文件
[root@localhost conf.d]# cat default.conf
server {
listen 80;
server_name www.test.com;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
if ( $host ~* ^www.test.com$ ){
break;
}
if ( $host ~* ^(.*)\.test\.com ){
set $user $1;
rewrite .* http://www.test.com/$user permanent;
}
}
location /alice {
root /usr/share/nginx/html;
index index.html index.htm;
}
location /jcak {
root /usr/share/nginx/html;
index index.html index.htm;
}
}
4. return 指令
return 指令用于返回狀態(tài)碼給客戶端
應用環(huán)境:
server,location,if
示例1:
如果訪問的 .sh 結尾的文件則返回 403 操作拒絕錯誤
# 修改配置文件
[root@localhost conf.d]# cat default.conf
server {
listen 80;
server_name www.test.com;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
location ~* \.sh$ {
return 403;
}
}
示例1:
80轉443端口
# 修改配置文件
server {
listen 80;
server_name www.test.com;
access_log /var/log/nginx/http_access.log main;
return 301 https://www.test.com$request_uri;
}
server {
listen 443 ssl;
server_name www.test.com;
access_log /var/log/nginx/https_access.log main;
#ssl on;
ssl_certificate /etc/nginx/cert/2447549_www.test.com.pem;
ssl_certificate_key /etc/nginx/cert/2447549_www.test.com.key;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
ssl_prefer_server_ciphers on;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
}
[root@nginx-server ~]# curl -I http://www.test.com
HTTP/1.1 301 Moved Permanently
Server: nginx/1.16.0
Date: Wed, 03 Jul 2019 13:52:30 GMT
Content-Type: text/html
Content-Length: 169
Connection: keep-alive
Location: https://www.test.com/
三、last break 詳解
#
[root@localhost conf.d]# cd /usr/share/nginx/html/
[root@localhost html]# mkdir test
[root@localhost html]# echo "last" > test/last.html
[root@localhost html]# echo "break" > test/break.html
[root@localhost html]# echo "test" > test/test.html
# 修改配置文件
[root@localhost conf.d]# cat default.conf
server {
listen 80;
server_name localhost;
access_log /var/log/nginx/last.access.log main;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
location /break {
root /usr/share/nginx/html;
rewrite .* /test/break.html break;
}
location /last {
root /usr/share/nginx/html;
rewrite .* /test/last.html last;
}
location /test {
root /usr/share/nginx/html;
rewrite .* /test/test.html break;
}
}
注意:
last標記在本條 rewrite 規(guī)則執(zhí)行完后,會對其所在的 server { … } 標簽重新發(fā)起請求;break標記則在本條規(guī)則匹配完成后,停止匹配,不再做后續(xù)的匹配;
四、Nginx 的 https ( rewrite )
server {
listen 80;
server_name *.vip9999.top vip9999.top;
if ($host ~* "^www.vip9999.top$|^vip9999.top$" ) {
return 301 https://www.vip9999.top$request_uri;
}
if ($host ~* "^(.*).vip9999.top$" ) {
set $user $1;
return 301 https://www.vip9999.top/$user;
}
}
# Settings for a TLS enabled server.
server {
listen 443 ssl;
server_name www.vip9999.top;
location / {
root /usr/share/nginx/html;
index index.php index.html;
}
#pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
location ~ \.php$ {
root /usr/share/nginx/html;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
ssl on;
ssl_certificate cert/214025315060640.pem;
ssl_certificate_key cert/214025315060640.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 10m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
}
五、Apache 的 https ( rewrite )拓展
[root@localhost ~]# yum -y install httpd mod_ssl
[root@localhost ~]# vim /etc/httpd/conf.d/vip9999.conf
