一個很簡單的需求,就是靜態頁面請求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 項目而且是前后端
分離的項目