Node.js后端开发 - 进阶篇 #11 express框架之res.sendFile和res.render,传递模块数据,模板引擎(持续更新中)

本文深入探讨Express框架中res.sendFile与res.render函数的使用场景与差异,讲解如何在业务模块中返回HTML页面,并处理包含CSS和图片文件的静态资源加载。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

一、前言

二、res.sendFile和res.render 函数的区别?

1、handler.js 业务模块返回 html 页面

(1)加载的 html 页面,没有css文件和image图片文件

(2)加载的 html 页面,有css文件和image图片文件

(3)最终效果


一、前言

上几篇文章我们对exprss的 router.js 路由模块、handler.js 业务模块进行了封装介绍,详细可参见博文:Node.js后端开发 - 进阶篇 #9 express框架之路由模块的封装2(相对安全)Node.js后端开发 - 进阶篇 #10 express框架之封装handler.js模块 这篇文章我们将讲 res.sendFile和res.render 函数的区别?如何传递模块数据?服务器端如何响应css文件、image文件?以及模板引擎的一些知识

二、res.sendFile和res.render 函数的区别?

1、handler.js 业务模块返回 html 页面

(1)加载的 html 页面,没有css文件和image图片文件

上篇文章我们封装了 handler.js 文件


//业务模块

//暴露函数,并且需要传入req、res参数,
//才能处理相应的业务,向用户响应
module.exports.index = function (req, res) {
    res.send('这个是 handler.index 方法中的代码');
};

它返回响应的是一些简单的文字信息: res.send('这个是 handler.index 方法中的代码'); ,我们现在来尝试返回一些 html 页面,我们新建一个 index.html,然后把相关resources资源文件放到项目里面。那么要用户看到 index.html 页面很简单,只要读取 index.html 页面的内容,然后响应给用户就行了。

我们可以用到前几篇文章讲到的 res.sendFile() 方法,要先拼接一下 index.html 的路径,要拼接路径我们先要加载 path 模块 ,我们来看下修改后的 handler.js 文件


//业务模块

var path = require('path');

//暴露函数,并且需要传入req、res参数,
//才能处理相应的业务,向用户响应
module.exports.index = function (req, res) {
    //res.send('这个是 handler.index 方法中的代码');

    //它后面的参数,回调函数可不写,它也会把信息数据返回给用户
    res.sendFile(path.join(__dirname, 'views', 'index.html'));

};

我们运行服务器端程序,然后在浏览器中输入地址:http://localhost:3000/

             

 这样可以看到网页信息,但是有很大的问题,因为css文件和image图片文件都没有。

 当请求css文件、图片文件的时候,服务器返回的是404。那么为什么会这样?

因为我们对用户请求的这些静态资源文件,服务器并没有做处理。那么我们怎么做处理呢?

(2)加载的 html 页面,有css文件和image图片文件

我们可以用到前几篇文章讲到的 通过express模拟Apache实现静态资源托管服务 的一些知识,详见可参考博文:Node.js后端开发 - 进阶篇 #6 express框架之通过express模拟Apache实现静态资源托管服务 ,我们修改下路由模块 router.js 里面的代码,实现对 resources 文件下的内容进行静态资源托管,核心代码如下

// 实现对 resources 文件下的内容进行静态资源托管
// /resources/css/MyStyle.css
router.use('/resources', express.static(path.join(__dirname, 'resources')));

(3)最终效果

我们运行服务器端程序,在浏览器中输入地址:http://localhost:3000/ ,最终效果如下图,css样式 和 图片文件都加载出来了

更新中。。。。。

<think>嗯,用户想了解Node.jsExpress框架的工作流程图。首先,我需要回忆一下Node.jsExpress的基本架构,以及它们如何处理请求的流程。 Node.js是基于事件驱动的非阻塞I/O模型,使用单线程的事件循环来处理并发请求。而Express是一个基于Node.js的Web框架,提供了路由、中间件等机制来简化开发。工作流程应该从接收HTTP请求开始,经过一系列中间件处理,然后路由到相应的处理函数,最后返回响应。 可能需要先画出整个流程的大致步骤,比如客户端发起请求,进入Node.js的HTTP服务器,然后由Express处理。中间件可能包括日志记录、解析请求体、静态文件服务等。然后路由分发到对应的控制器,进行业务逻辑处理,访问数据库或其他服务,生成响应,再经过中间件返回给客户端。 需要注意的是,中间件的执行顺序很重要,每个中间件按顺序执行,可以修改请求响应对象,或者结束请求-响应周期。错误处理中间件应该放在最后,捕获处理过程中的错误。 另外,用户提到的引用中有关于项目结构的内容,比如引用[1]提到代码结构对可维护性的重要性,引用[2]涉及建立Web服务器的步骤,引用[3]关于模板引擎。这些可能在架构图中不直接相关,但项目结构可能影响工作流程的组织,比如路由中间件的配置位置。 可能用户需要的是一个分层架构图,展示从底层Node.jsExpress中间件、路由、控制器、模型、数据库的流程。或者更详细的请求处理流程图,显示每个步骤的顺序组件之间的交互。 需要确保流程图的描述清晰,步骤分明,涵盖主要组件如HTTP Server、Middleware Stack、Routing、Controllers、Models、Database等,并说明它们之间的关系数据流向。同时,结合引用中的项目结构,说明各个部分在代码中的组织方式,比如routes文件夹存放路由定义,middleware文件夹放置中间件等。 可能还需要提到事件循环的角色,以及非阻塞I/O如何影响性能。比如,Node.js的事件循环处理多个请求,而Express中间件路由处理每个请求的具体逻辑,确保不会阻塞主线程。 最后,生成的问题需要围绕工作流程的细节、中间件的作用、架构优势、常见错误处理等,帮助用户进一步理解。</think>### Node.js + Express 工作流程架构解析 以下是Node.jsExpress框架处理HTTP请求的典型工作流程及架构图描述: ```plaintext +---------------------+ | 客户端发起HTTP请求 | +----------+----------+ | v +----------+----------+ | Node.js HTTP Server | | (底层TCP连接/事件循环) | +----------+----------+ | v +----------+----------+ | Express框架入口(app) | | (中间件栈初始化/路由配置)| +----------+----------+ | | 中间件顺序执行: | 1. 日志记录(morgan) | 2. 请求体解析(body-parser) | 3. 静态文件服务(express.static) | 4. 自定义中间件... v +----------+----------+ | 路由匹配(Router) | | (路径+方法匹配处理器) | +----------+----------+ | v +----------+----------+ | 控制器(Controller) | | (业务逻辑处理/数据库操作)| +----------+----------+ | v +----------+----------+ | 响应生成(JSON/模板引擎)| +----------+----------+ | v +----------+----------+ | 返回HTTP响应给客户端 | +---------------------+ ``` ### 关键组件说明 1. **Node.js HTTP Server** 基于事件循环的非阻塞I/O模型,通过`http.createServer()`创建服务实例,负责底层TCP连接管理请求分发[^2]。 2. **Express中间件栈** - 中间件按`app.use()`顺序执行,可修改请求/响应对象或终止请求 - 常用中间件如`morgan`(日志)、`cors`(跨域)、`helmet`(安全头)等 - 示例代码结构: ```javascript app.use(express.json()); // 解析JSON请求体 app.use(&#39;/static&#39;, express.static(&#39;public&#39;)); // 静态文件路由 ``` 3. **路由系统** - 通过`app.get()/post()`定义路径与方法映射 - 模块化路由可通过`express.Router()`拆分到不同文件[^1] ```javascript // routes/user.js const router = express.Router(); router.get(&#39;/profile&#39;, (req, res) => {...}); ``` 4. **控制器与业务逻辑** 处理具体业务,包含数据库操作(如Mongoose)、API调用等异步操作,需注意错误处理: ```javascript exports.getUser = async (req, res, next) => { try { const user = await User.findById(req.params.id); res.render(&#39;user-profile&#39;, { user }); } catch (err) { next(err); // 传递至错误处理中间件 } } ``` 5. **响应生成** 支持多种响应方式: - `res.json()`:返回JSON数据 - `res.render()`:使用模板引擎(如EJS[^3])生成HTML - `res.sendFile()`:发送静态文件 ### 架构优势 - **中间件管道**:通过组合中间件实现功能扩展 - **非阻塞处理**:利用Node.js异步特性支持高并发 - **模块化结构**:符合MVC模式,便于协作开发
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

被开发耽误的大厨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值