静态文件请求路径 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

posted on 2020-07-17 11:30  荣锋亮  阅读(1413)  评论(0编辑  收藏  举报

导航