靜態文件請求路徑 rewrite nginx && openresty 實現


一個很簡單的需求,就是靜態頁面請求url 的rewrite 方便使用,類似mvc 的路由,不同的請求,對應到后邊不同的website,但是是一個地址
作用:類似一種micro frontend 的一些部分功能實現,這樣靜態web site 就有了一個統一而且靈活的入口 ,比較適合sass,或者用戶有特定
需求的場景

格式處理

  • 原有請求格式參考
    html 后綴是可選的
 
http://<domain>:<port>/<subpath>/<webpage><.html?>
  • 調整為的格式
http://<domain>:<port>/<web><.html?>/<id>
  • website 部署規則說明
subpath的命名為<prefix>/<id>

正則規則

需求比較明確了,rewrite 我們基於正則處理,所以需要先梳理出來正則的格式
參考格式:

 
^(.*?)(.html)?\/(\d)$

說明 任意字符開始 .html 開頭以及結尾是可選的,同時以數字開頭的(目前只處理了一個數字的,多個也很簡單)

^(.*?)(.html)?\/(\d+)$

重寫處理使用了正則的分組匹配
格式:

 
/demo$3$1

基於nginx rewrite 的實現

  • 參考部署目錄結構
    說明demo1 以及demo2是我們需要部署的website,為了給用戶一個清晰,簡單的訪問入口,原有提供的格式成為內部(nginx 使用internal)
 
├── README.md
├── demoapps
│   ├── 404.html
│   ├── default
│   │   └── index.html
│   ├── demo1
│   │   ├── css1
│   │   │   └── index.css
│   │   ├── index
│   │   ├── index.html
│   │   └── js1
│   ├── demo2
│   │   ├── css2
│   │   │   └── index.css
│   │   ├── index
│   │   ├── index.html
│   │   └── js2
│   ├── favicon.ico
│   └── index.html
├── docker-compose.yaml
├── nginx.conf
 
 

為了簡單使用了demo 的prefix

  • nginx 配置
    說明使用rewrite 的正則匹配,內容部分使用了openresty, rewrite 使用了last 模式的
    server {
       listen 80;
       charset utf-8;
       default_type text/html;
       location / {
            root /opt/demoapps/;
            index index.html index.htm index;
            # 不同規則的重寫(比如固定的幾個),注意last 與break 的區別
            rewrite ^(.*?)(.html)?\/(\d)$ /demo$3$1 last;
            # rewrite ^(.*?)(.html)?\/2$ /demo2$1 last;
       }
       error_page 404 /404.html;
       # 不存在默認界面
       location = /404.html {
            root /opt/demoapps/;
       }
       location /css1 {
            root /opt/demoapps/demo1;
       }
       location /css2 {
            root /opt/demoapps/demo2;
       }
       location =/favicon.ico {
            root /opt/demoapps/;
       }
       # 可以基於openresty 的處理,此處可以基於web 框架處理比如 lua-resty-route 以及lua-resty-template
       location ~* ^/demo {
           internal;
           root /opt/demoapps/;
        #   content_by_lua_block {
        #       local cjson = require("cjson.safe")
        #       local args, err = ngx.req.get_uri_args()
        #       if err == "truncated" then
        #           ngx.say(cjson.encode([[fetch error]]))
        #       end
        #       local body = {
        #           args = args,
        #           url = ngx.var.request_uri
        #       }
        #       ngx.say(cjson.encode(body))
        #   }
       }
    } 
 
 
  • 基於openresty 的配置
    通過rewrite_by_lua_block 階段處理
 
server {
       listen 8080;
       charset utf-8;
       default_type text/html;
       location / {
            root /opt/demoapps/;
            index index.html index.htm index;
            rewrite_by_lua_block {
                local uri,n,err = ngx.re.sub(ngx.var.uri, [[^(.*?)(.html)?\/(\d)$]], "/demo$3$1", "o")
                ngx.log(ngx.ERR,"fetch"..uri)
                local newuri = "/default"
                if n >  0 then
                   newuri = uri
                end
                ngx.req.set_uri(newuri,true)
            }
       }
       location /css1 {
            root /opt/demoapps/demo1;
       }
       location /css2 {
            root /opt/demoapps/demo2;
       }
       location =/favicon.ico {
            root /opt/demoapps/;
       }
       error_page 404 /404.html;
       # 不存在默認界面
       location = /404.html {
            root /opt/demoapps/;
       }
       location /default/ {
            root /opt/demoapps/;
       }
       # 基於openresty 的處理,此處可以基於web 框架處理比如 lua-resty-route 以及lua-resty-template
       location ~* ^/demo {
           internal;
           index index.html index.htm index;
           root /opt/demoapps/;
        #   content_by_lua_block {
        #       local cjson = require("cjson.safe")
        #       local args, err = ngx.req.get_uri_args()
        #       if err == "truncated" then
        #           ngx.say(cjson.encode([[fetch error]]))
        #       end
        #       local body = {
        #           args = args,
        #           url = ngx.var.request_uri
        #       }
        #       ngx.say(cjson.encode(body))
        #   }
       }
    } 
 
 
  • docker-compose 文件
version: "3"
services: 
  api:
    image: openresty/openresty:alpine
    volumes:
    - "./nginx.conf:/usr/local/openresty/nginx/conf/nginx.conf"
    - "./demoapps:/opt/demoapps"
    ports:
    - "80:80"
    - "8080:8080"

效果

80 與8080的效果是一樣的
默認頁面

 

 


不同用戶的website

 

 

說明

基於nginx 的rewrite或者使用openresty 的rewrite_by_lua_block 階段,我們可以實現靜態website的動態路由能力,高效而且方便,同時實際我們
使用的過程中基於s3或者oss 等效果會更好,可以讓靜態頁面不在單一,而是具有了靈活的控制能力,比較適合復雜的website 項目而且是前后端
分離的項目

參考資料

https://github.com/rongfengliang/openresty_rewrite_static


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM