zoukankan      html  css  js  c++  java
  • 静态文件请求路径 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

  • 相关阅读:
    Flask-SQLAlchemy 学习总结
    ubuntu安装redis
    PostgreSQL在Ubuntu上安装指南
    Linux(Ubuntu)下MySQL的安装与配置
    python wechat_sdk间接性的出现错误OfficialAPIError: 40001,说access_token已过期或者不是最新的。
    django不要设置datetime字段auto_now=True
    python 装饰器和 functools 模块
    关于 Python Iterator 协议的一点思考
    python中的enumerate函数
    8 种常被忽视的 SQL 错误用法
  • 原文地址:https://www.cnblogs.com/rongfengliang/p/13328863.html
Copyright © 2011-2022 走看看