### Install Leizm-Web Source: https://github.com/leizongmin/leizm-web/blob/main/README.md Install the Leizm-Web package using npm. ```bash npm i @leizm/web -S ``` -------------------------------- ### Hello World Example Source: https://github.com/leizongmin/leizm-web/blob/main/README.md A basic 'Hello, World!' example demonstrating app initialization, template rendering, JSON response, and listening on a port. ```typescript import * as web from "@leizm/web"; // 创建app实例 const app = new web.Application(); // 快速初始化 ejs 模板,需要手动安装 ejs 模块 app.templateEngine.initEjs(); app.router.get("/a", async function(ctx) { // 渲染模板,模板文件为 views/index.html ctx.response.render("index", { msg: "hello, world" }); }); app.router.get("/b", async function(ctx) { // 返回JSON ctx.response.json({ msg: "hello, world" }); }); // 监听端口 app.listen({ port: 3000 }); ``` -------------------------------- ### Basic Session Middleware Usage Source: https://github.com/leizongmin/leizm-web/wiki/session-中间件 Demonstrates the basic setup and usage of the session middleware with Redis storage. Ensure cookieParser is used before session middleware. Session data can be accessed via `ctx.request.session` or `ctx.session.data`, and manipulated using methods like `reload`, `regenerate`, `destroy`, and `touch`. ```typescript import { Application, component } from "@leizm/web"; const app = new Application(); // 需要注意的是,引入 session 中间件前必须引入 cookieParser 中间件 app.use("/", component.cookieParser()); app.use("/", component.session({ /** 存储引擎实例 */ store: new component.SessiionRedisStore({ host: "127.0.0.1", port: 6379, }), /** Cookie名称 */ name: ”web.sid“, /** Cookie选项 */ cookie: { signed: true }, /** Session有效时间(单位:毫秒),此参数会覆盖cookie中的maxAge */ maxAge: 3600, })); app.use("/", async function (ctx) { // 可通过 ctx.request.session 获取 Session 数据 console.log(ctx.request.session); // 也可通过 ctx.session.data 获取 Session 数据 console.log(ctx.session.data); // 另外可以通过 ctx.session 操作 Session await ctx.session.reload(); await ctx.session.regenerate(); await ctx.session.destroy(); await ctx.session.touch(); }); ``` -------------------------------- ### Extending Request and Response Objects Source: https://github.com/leizongmin/leizm-web/blob/main/README.md Example of extending the Request and Response objects with custom methods like `remoteIP`, `ok`, and `error`. This code is intended to be imported locally instead of from the `@leizm/web` package. ```typescript import * as base from "@leizm/web"; export * from "@leizm/web"; export type MiddlewareHandle = (ctx: Context, err?: base.ErrorReason) => Promise | void; export class Application extends base.Application { protected contextConstructor = Context; } export class Router extends base.Router { protected contextConstructor = Context; } export class Context extends base.Context { protected requestConstructor = Request; protected responseConstructor = Response; } export class Request extends base.Request { // 扩展 Request public get remoteIP() { return String(this.req.headers["x-real-ip"] || this.req.headers["x-forwarded-for"] || this.req.socket.remoteAddress); } } export class Response extends base.Response { // 扩展 Response public ok(data: any) { this.json({ data }); } public error(error: string) { this.json({ error }); } } ``` -------------------------------- ### Basic Usage with Middleware Source: https://github.com/leizongmin/leizm-web/blob/main/README.md Demonstrates basic middleware usage, including built-in middleware like cookieParser, custom synchronous and asynchronous middleware, router integration, and error handling. ```typescript import * as web from "@leizm/web"; const app = new web.Application(); const router = new web.Router(); // 使用内置中间件 app.use("/", web.component.cookieParser()); // 基本的中间件 app.use("/", function(ctx) { console.log("hello, world"); ctx.next(); }); // 支持 async function app.use("/", async function(ctx) { console.log("async function"); await sleep(1000); ctx.next(); }); // 路由中间件 router.get("/hello/:a/:b", function(ctx) { console.log("a=%s, b=%s", ctx.request.params.a, ctx.request.params.b); ctx.response.html("it works"); }); app.use("/", router); // 错误处理 app.use("/", function(ctx, err) { ctx.response.json({ message: err.message }); }); // 监听端口 app.listen({ port: 3000 }, () => { console.log("server started"); }); ``` -------------------------------- ### 使用 app.server 进行单元测试 Source: https://github.com/leizongmin/leizm-web/wiki/单元测试 通过 `app.server` 获取原始的 `http.Server` 实例,无需 `listen()` 监听端口。适用于使用 supertest 或 superagent 进行集成测试。 ```typescript import { Application } from "@leizm/web"; import * as request from "supertest"; describe("单元测试", function () { it("使用app.server", async function () { const app = new Application(); await request(app.server).get("/").expect(200); }); }); ``` -------------------------------- ### 将 Connect 中间件转换为 @leizm/web 格式 Source: https://github.com/leizongmin/leizm-web/wiki/兼容-connect-中间件 使用 `fromClassicalHandle` 函数将 Connect 中间件(如 `body-parser`)转换为 @leizm/web 应用可用的格式。适用于需要利用现有 Connect 中间件生态的场景。 ```typescript import { Application, fromClassicalHandle } from "@leizm/web"; import * as bodyParser from "body-parser" const app = new Application(); // 通过 fromClassicalHandle 函数转换 connect 中间件 app.use("/", fromClassicalHandle(bodyParser.json())); app.use("/", fromClassicalHandle(function (req, res, next) { // 自定义 connect 中间件 // ... next(); })); ``` -------------------------------- ### 在 Connect 中使用 @leizm/web 中间件 Source: https://github.com/leizongmin/leizm-web/wiki/兼容-connect-中间件 使用 `toClassicalHandle` 函数将 @leizm/web 格式的中间件转换为 Connect 可用的格式。这允许你在 Connect 应用中复用 @leizm/web 的中间件逻辑。 ```typescript import { Application, toClassicalHandle } from "@leizm/web"; import * as connect from "connect"; const app = new Application(); // 通过 app.handleRequest 方法处理请求 const app2 = connect(); app2.use(app.handleRequest); // 转化 @leizm/web 格式中间件 app2.use(toClassicalHandle(function (ctx) { console.log('中间件已经执行'); ctx.next(); })); ``` -------------------------------- ### Basic BodyParser Middleware Usage Source: https://github.com/leizongmin/leizm-web/wiki/bodyParser-中间件 Integrate built-in BodyParser middleware for common content types. Refer to the body-parser npm package for initialization parameter details. ```typescript import { Application, component } from "@leizm/web"; const app = new Application(); // 以下中间件基于 body-parser 模块实现 // 初始化参数用法可以参考 https://www.npmjs.com/package/body-parser app.use("/", component.bodyParser.json()); app.use("/", component.bodyParser.text()); app.use("/", component.bodyParser.urlencoded()); app.use("/", component.bodyParser.raw()); // 以下中间件基于 busboy 模块实现 // 初始化参数用法可以参考 https://www.npmjs.com/package/busboy app.use("/", component.bodyParser.multipart()); app.use("/", async function (ctx) { // body 数据可以通过 ctx.request.body 获取 console.log(ctx.request.body); // files 数据可以通过 ctx.request.files 获取 console.log(ctx.request.files); ctx.end(); }); ``` -------------------------------- ### Multipart Parsing with Small File Size Option Source: https://github.com/leizongmin/leizm-web/wiki/bodyParser-中间件 Configure multipart parsing to handle small files efficiently by storing them in memory. Files larger than 'smallFileSize' are saved to a temporary directory. ```typescript app.use("/", async function (ctx) { // 解析 multipart/form-data const { body, files } = await ctx.request.parseMultipart({ smallFileSize: 1024 * 100 }); console.log(body, files); for (const n of files) { const file = files[n]; if (file.path) { console.log("%s 文件路径:%s", n, file.path); } else { console.log("%s 文件内容:%s", n, file.buffer); } } }); ``` -------------------------------- ### SessionStore Interface Definition Source: https://github.com/leizongmin/leizm-web/wiki/session-中间件 Defines the interface for a custom session store. Any object implementing this interface can be used with the session middleware. ```typescript interface SessionStore { /** * 获取session * @param sid */ get(sid: string): Promise>; /** * 设置session * @param sid * @param data * @param maxAge */ set(sid: string, data: Record, maxAge: number): Promise; /** * 销毁Session * @param sid */ destroy(sid: string): Promise; /** * 保持session激活 * @param sid * @param maxAge */ touch(sid: string, maxAge: number): Promise; } ``` -------------------------------- ### Custom JSON Body Parser Source: https://github.com/leizongmin/leizm-web/wiki/使用原始的-req-和-res-对象 Implement a custom JSON body parser by directly accessing the raw request object. This snippet demonstrates how to listen for 'data' and 'end' events on `ctx.request.req` to capture and parse the request body. ```typescript // 自己实现一个 JSON body parser app.use(function (ctx) { // 判断 Content-Type 是否为 application/json const type = ctx.request.getHeader('content-type'); if (!type || String(type).toLowerCase().indexOf('application/json') === -1) { return ctx.next(); } // 通过 data 和 end 事件获取请求 body 的内容 const list: Buffer[] = []; ctx.request.req.on('data', chunk => list.push(chunk as Buffer)); ctx.request.req.on('end', () => { // 通过 JSON.parse() 解析 body,并且保存到 ctx.request.body try { ctx.request.body = JSON.parse(Buffer.concat(list).toString()); } catch (err) { return ctx.next(err); } ctx.next(); }); }); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.