openresty 前端开发轻量级MVC框架封装一(控制器篇)

简介:

通过前面几章,我们已经掌握了一些基本的开发知识,但是代码结构比较简单,缺乏统一的标准,模块化,也缺乏统一的异常处理,这一章我们主要来学习如何封装一个轻量级的MVC框架,规范以及简化开发,并且提供类似php所见即所得的能力

统一入口

通常来说一个mvc框架会有一个统一的入口点,类似于spring mvc的DispatcherServlet,会拦截所有的请求,也就是/,于是我们可以得出我们的入口点

conf/nginx.conf

worker_processes  1;

error_log logs/error.log notice;

events {
    worker_connections 1024;
}

http {
    lua_package_path "/Users/john/opensource/openresty-web-dev/demo8/lua/?.lua;/Users/john/opensource/openresty-web-dev/demo8/lualib/?.lua;/usr/local/openresty/lualib/?.lua";
    server {
        listen 80;
        server_name localhost;
        lua_code_cache off;

        location / {
            content_by_lua_file lua/mvc.lua;
        }

        location ~ ^/js/|^/css/|\.html {
            root html;
        }
    }
}

除了静态文件js/css/html文件,其他的请求都会被我们的mvc.lua处理。

默认页面

当请求uri为空时,默认返回index.html页面,当然也可以自己定义,实现这个效果很简单

local uri = ngx.var.uri
-- 默认首页
if uri == "" or uri == "/" then
    local res = ngx.location.capture("/index.html", {})
    ngx.say(res.body)
    return
end

url解析

这里简单的把url解析成模块名模块方法,根据/分割,如果只有模块名,没有方法名,则默认为index方法

local m, err = ngx.re.match(uri, "([a-zA-Z0-9-]+)/*([a-zA-Z0-9-]+)*")

local moduleName = m[1]     -- 模块名
local method = m[2]         -- 方法名

if not method then
    method = "index"        -- 默认访问index方法
else
    method = ngx.re.gsub(method, "-", "_")    
end

动态Controller模块

得到模块名之后,需要动态引入模块,通过pcall,然后再调用模块的方法

-- 控制器默认在web包下面
local prefix = "web."       
local path = prefix .. moduleName

-- 尝试引入模块,不存在则报错
local ret, ctrl, err = pcall(require, path)

local is_debug = true       -- 调试阶段,会输出错误信息到页面上

if ret == false then
    if is_debug then
        ngx.status = 404
        ngx.say("<p style='font-size: 50px'>Error: <span style='color:red'>" .. ctrl .. "</span> module not found !</p>")
    end
    ngx.exit(404)
end

-- 尝试获取模块方法,不存在则报错
local req_method = ctrl[method]

if req_method == nil then
    if is_debug then
        ngx.status = 404
        ngx.say("<p style='font-size: 50px'>Error: <span style='color:red'>" .. method .. "()</span> method not found in <span style='color:red'>" .. moduleName .. "</span> lua module !</p>")
    end
    ngx.exit(404)
end

-- 执行模块方法,报错则显示错误信息,所见即所得,可以追踪lua报错行数
ret, err = pcall(req_method)

if ret == false then
    if is_debug then
        ngx.status = 404
        ngx.say("<p style='font-size: 50px'>Error: <span style='color:red'>" .. err .. "</span></p>")
    else
        ngx.exit(500)
    end
end

异常处理

可以看到,从引入模块,到获取模块方法,已经执行方法,都有可能报错,这里通过pcall来进行调用,这种方式可以安全的调用lua代码,不会导致异常中断,然后通过定义一个变量,来区分是否为开发调试阶段,如果是则把错误信息输出到浏览器端,否则直接报404或者500,避免把错误信息输出到客户端,导致代码泄漏。

至此,一个简单的mvc框架已经可以使用了,但是现在还只能做前端渲染,下一章,我讲介绍如果进行服务端渲染。

示例代码 参见demo8部分

目录
相关文章
|
22天前
|
监控 前端开发 API
一款基于 .NET MVC 框架开发、功能全面的MES系统
一款基于 .NET MVC 框架开发、功能全面的MES系统
|
3月前
|
存储 NoSQL 前端开发
前端轻量级数据库mongodb
【10月更文挑战第2天】MongoDB 是一个基于分布式文件存储的开源数据库系统,不属于前端轻量级数据库,而是后端数据库。它使用 BSON 格式存储数据,支持复杂的数据结构,适用于内容管理系统、物联网等领域。MongoDB 通过动态模式和面向对象的数据存储方式,提供了灵活的数据模型。在 Web 应用中,它通常作为后端存储,通过 API 与前端交互,实现高效的数据管理和实时更新。
|
3月前
|
前端开发 Java
【案例+源码】详解MVC框架模式及其应用
【案例+源码】详解MVC框架模式及其应用
236 0
|
5月前
|
缓存 前端开发 Java
【前端学java】java基础巩固复习巩固语法练习-工具类的封装(14)
【8月更文挑战第10天】java基础巩固,工具类的封装
35 1
|
5月前
|
数据采集 资源调度 JavaScript
Node.js 适合做高并发、I/O密集型项目、轻量级实时应用、前端构建工具、命令行工具以及网络爬虫和数据处理等项目
【8月更文挑战第4天】Node.js 适合做高并发、I/O密集型项目、轻量级实时应用、前端构建工具、命令行工具以及网络爬虫和数据处理等项目
79 5
|
5月前
|
设计模式 存储 前端开发
MVC 框架的主要问题是什么?
【8月更文挑战第30天】
110 0
|
6月前
|
开发框架 前端开发 JavaScript
循序渐进VUE+Element 前端应用开发(13)--- 前端API接口的封装处理
循序渐进VUE+Element 前端应用开发(13)--- 前端API接口的封装处理
|
6月前
|
前端开发 JavaScript 开发者
前端 JS 经典:通用性函数封装思路
前端 JS 经典:通用性函数封装思路
44 0
|
6月前
|
前端开发 JavaScript
前端 JS 经典:封装全屏功能
前端 JS 经典:封装全屏功能
49 0
|
7月前
|
安全 前端开发 测试技术
安全开发-PHP应用&模版引用&Smarty渲染&MVC模型&数据联动&RCE安全&TP框架&路由访问&对象操作&内置过滤绕过&核心漏洞
安全开发-PHP应用&模版引用&Smarty渲染&MVC模型&数据联动&RCE安全&TP框架&路由访问&对象操作&内置过滤绕过&核心漏洞

热门文章

最新文章