5G時代,URL Rewrite 還吃香嗎
阿新 • • 發佈:2020-11-23
URL Rewrite是網站建設中經常用到的一項技巧,通過 rewrite 我們能夠遮蔽伺服器執行態的資訊,包括服務的程式、引數等等,給使用者呈現美化後的URL,同時對搜尋引擎更加友好,方便我們網站的推廣。
[TOC]
## rewrite 功能介紹
URL是網際網路上指定資訊的唯一標誌,URL Rewrite 就是常說的地址重寫,我們一般常說的地址重寫主要是針對 HTTP 或 HTTPS 協議,具體的場景有下面幾種。
* 美化URL。不管使用哪種後臺語言,多多少少會有一些能夠暴露技術特性的字尾,例如 `.php` 、`.do` 等等。URL重寫後,去掉了這些對於普通使用者難於理解的字尾,也有利於網站後臺的安全。
* 提高安全性。可以對一個域名下的所有服務進行重寫,只開放對外的服務。對於不開放服務的訪問,重定向到404或者500頁面,避免被人暴力猜解。
* 有利於搜尋引擎收錄。有些後臺服務的功能很強大,但是為了按照業務拆分,我們可以設計一些後臺並不存在的URL,利於搜尋引擎的收錄和業務的開展。
* 方便URL的重用一記後臺服務的調整。如果我們後臺進行了版本升級或者地址變更,都可以通過URL Rewrite對外部使用者遮蔽這些變化,極大的方便了網站的維護。
這些場景可以用下圖來概括說明。
![](https://img2020.cnblogs.com/blog/39469/202011/39469-20201123155053159-1346352742.png)
有的朋友會發出疑問,在PC時代,大家首先面對的就是網站的地址,但是2020已經快要步入5G時代,大多數人都是通過手機APP來訪問網際網路上的各種內容。根據 CNNIC 《[第46次中國網際網路絡發展狀況統計報告](http://www.cnnic.net.cn/hlwfzyj/hlwxzbg/hlwtjbg/202009/P020200929546215182514.pdf)》顯示我國網民使用手機上網的比例達99.2%,而使用桌上型電腦和筆記本上網的網民比例分別是37.3%和31.8%。使用手機上網,很多情況下我們都是掃描一個二維碼或者點選分享的連結就能開啟頁面,而無需再記憶複雜的URL,那麼是否可以說在5G時代,URL Rewrite 就不重要了呢?
實際上,網站服務除了被使用者訪問外,每天都會被搜尋引擎、黑產分子不停的訪問,在5G時代即便使用者不需要手工輸入URL來訪問,合理利用URL Rewrite這項技術仍是每個網站開發人員、網站維護人員不可缺少的技能。
URL Rewrite的方法有很多,可以利用Apache、Nginx等中介軟體,也可以使用支援單入口的程式框架(例如PHP的Codeigniter)等,本文介紹如何使用Nginx來實現URL Rewrite的需求,畢竟Nginx近年來的發展勢頭那真是勢不可擋。
## nginx rewrite
Nginx提供了rewrite功能,結合正則表示式和標誌位實現URL的重寫與重定向,正則規則採用PCRE(PERL相容的正則表示式語法規則)。
> 如果需要正則功能,在編譯Nginx之前,需要編譯安裝PCRE庫。
rewrite 規則只能放在`server{}`,`location{}`,`if{}`中,並且只能對域名後邊除去傳遞的引數外的字串起作用。。
### rewrite 語法
rewrite 是實現URL重寫的關鍵,根據正則表示式的內容,重新定向到replacement指定的URL,根據末尾的flag引數不同,決定後續的處理動作。
| 指令語法 | rewrite regex replacement [flag] |
| -------- | -------------------------------- |
| 預設值 | none |
| 應用位置 | server、location、if |
簡單的示例:
```nginx
# URL實現偽靜態,將動態引數變為URL中的字串
rewrite ^/users/(.*)$ /show.php?user=$1? last;
# 實現不同語言網站的跳轉
rewrite ^/cn/(.*)$ /cn/$1 break;
rewrite ^/jp/(.*)$ /jp/$1 break;
# 將所有的請求都定向到 baidu.com
rewrite ^/(.*) http://www.baidu.com/ permanent;
```
在Nginx的配置中,優先執行 server 塊中的 rewrite 指令,然後再執行 location 塊中的 rewrite 指令。最後再執行選定的 location 中的 rewrite 指令。
### flag標記
| flag標記符號 | 說明 |
| ------------ | ------------------------------------------------------------ |
| last | 本條規則匹配完成後,繼續向下匹配新的 location URI 規則,瀏覽器位址列URL地址顯示原來的地址 |
| break | 本條規則匹配完成即終止,不再匹配後面的任何規則,瀏覽器位址列URL地址顯示原來的地址 |
| redirect | 返回302臨時重定向,瀏覽器位址列會顯示跳轉後的URL地址 |
| permanent | 返回301永久重定向,瀏覽器位址列會顯示跳轉後的URL地址 |
在flag標記中,`last` 和 `break` 實現功能類似,使用 `alias` 指令時必須用 `last` 標記,使用 `proxy_pass` 指令時要使用 `break` 標記。`last` 標記在本條 rewrite 規則執行完畢後,會對其所在的 `server{…}` 標籤重新發起請求,而 `break` 標記則會在本條規則匹配完成後,終止匹配,不再匹配後面的規則。
### 實戰案例
本文提供了一個基於 docker 的演示案例,將上文的場景一一演示出來。通過訪問 [我的Github](https://github.com/cocowool/sh-valley/tree/master/docker-conf/lnmp) 可以獲得全部的 docker 編排檔案及程式碼。
> 不太熟悉 Docker 的同學可以參考 [使用 Docker 快速搭建LNMP開發環境](http://edulinks.cn/2020/04/17/20200415-qucik-lnmp-dev-environment/),讓你在安裝了 Docker 的情況下,使用一條命令就快速搭建LNMP開發環境。還要了解更多 Docker 的內容,可以檢視 [Docker 系列文章](http://edulinks.cn/2020/10/16/20201016-kubernetes-articles/#Docker-系列文章)
![](https://img2020.cnblogs.com/blog/39469/202011/39469-20201123155110951-204696216.png)
![](https://img2020.cnblogs.com/blog/39469/202011/39469-20201123155116871-1578504035.png)
主要的語法如下
```nginx
rewrite ^/login$ /login.php last;
rewrite ^/register$ /register.php last;
rewrite ^/search$ /search.php last;
rewrite ^/discount/student$ /discount.php?u=d last;
rewrite ^/discount/teacher$ /discount.php?u=t last;
```
Nginx Rewrite 還有更多強大的功能,等待大家去探索,歡迎關注我的公眾號與我進行交流探討。
## 參考資料
1. [IETF RFC 1630](https://datatracker.ietf.org/doc/rfc1630/?include_text=1)
2. [Ngx_http_rewrite_module](http://nginx.org/en/docs/http/ngx_http_rewrite_module.html)
3. [nginx中try_files](https://www.cnblogs.com/boundless-sky/p/9459775.html)
4. [Nginx rewrite or internal redirection cycle while internally redirecting](https://stackoverflow.com/questions/37214921/nginx-rewrite-or-internal-redirection-cycle-while-internally-redirecting)
5. [Nginx rewrite](https://blog.csdn.net/qq_41475058/article/details/89516051)