Node学习(五)021-处理静态资源——中间件是express最大特色-app.use() & 有三个基本参数req、res、next & 自定义中间件处理静态资源文件-sendFile异步读取文件

Node学习(五)021-处理静态资源——中间件是express最大特色-app.use() & 有三个基本参数req、res、next & 自定义中间件处理静态资源文件-sendFile异步读取文件

2.3 处理静态资源文件

方案一:使用 app.get(‘*’, (req, res) => { 根据请求的url做出响应 }); ---- 不推荐

方案二:使用官网提供的中间件的方法来处理。

const express = require('express');
const app = express();
app.listen(3000, () => console.log('又开启了'));

// 通过如下代码就可以将 manager 目录下的图片、CSS 文件、JavaScript、html文件 对外开放访问了
app.use(express.static('manager'));

// 处理浏览器的请求,响应一个index.html  效果一
// app.get('/index.html', (req, res) => {
//     res.sendFile(__dirname + '/manager/index.html');
// });

效果一

在这里插入图片描述

实例

实例1:01-处理静态资源文件.js

const express = require('express');
const app = express();
app.listen(3000, () => console.log('又开启了'));

// 处理 /index.html
// app.get('/index.html', (req, res) => {
//     res.sendFile(__dirname + '/manager/index.html');
// });
app.get('/time', (req, res) => {
    res.send(Date.now() + ''); // 21423523 + ''
});

// * 表示所有的GET请求
app.get('*', (req, res) => {
    // console.log(req.url);
    res.sendFile(__dirname + '/manager' + decodeURIComponent(req.url));
});

展示效果

在这里插入图片描述

2.4 中间件

为了理解中间件,我们先来看一下我们现实生活中的自来水厂的净水流程。

在这里插入图片描述

  • 在上图中,自来水厂从获取水源到净化处理交给用户,中间经历了一系列的处理环节
  • 我们称其中的每一个处理环节就是一个中间件。
  • 这样做的目的既提高了生产效率也保证了可维护性。

express中间件是一个特殊的url地址处理函数

  • 中间件是 express 的最大特色,也是最重要的一个设计
  • 一个 express 应用,就是由许许多多的中间件来完成的
  • 中间件就是一个函数,中间件函数要当做 app.use(); 的参数,这样来使用
  • 中间件函数中有三个基本参数, req、res、next
  • req就是请求相关的对象,它和后面用到的req对象是一个对象
  • res就是响应相关的对象,它和后面用到的res对象也是一个对象
  • next:它是一个函数,调用它将会跳出当前的中间件函数,执行后续代码;如果不调用next,则会在当前中间件卡住

在这里插入图片描述

错误的原因是,因为有两次响应,前面一次响应设置了响应头,后面又做出了响应;做出响应之后,有设置了响应头,所以就出现这个错误了。

以后如果遇到这个问题,首先思考当前这次请求是否有多次响应。

实例

利用 Express 托管静态文件 - Express 中文文档 | Express 中文网 (expressjs.com.cn)

例如,通过如下代码就可以将 public 目录下的图片、CSS 文件、JavaScript 文件对外开放访问了:

// 中间件
app.use(express.static('public'))

现在,你就可以访问 public 目录中的所有文件了:

http://localhost:3000/images/kitten.jpg
http://localhost:3000/css/style.css
http://localhost:3000/js/app.js
http://localhost:3000/images/bg.png
http://localhost:3000/hello.html

例子

02-处理静态资源文件.js

const express = require('express');
const app = express();
app.listen(3000, () => console.log('又开启了'));

// 通过如下代码就可以将 manager 目录下的图片、CSS 文件、JavaScript、html文件 对外开放访问了
     //  https://www.expressjs.com.cn/starter/static-files.html
app.use(express.static('manager')); // 此为中间件,详情内容见上述链接

// 处理浏览器的请求,响应一个index.html
// app.get('/index.html', (req, res) => {
//     res.sendFile(__dirname + '/manager/index.html');
// });

app.get('/time', (req, res) => {
    res.send(Date.now() + '');
});

2.5 自定义中间件处理静态资源文件的读取及响应

思路:

  • 如果发现请求的是静态资源(url以 /assets/ 开头),则读取他们,并返回。
  • 如果不是静态资源,则交给下一个中间件处理(next)
app.listen(3000, .....);
// 下面开始写中间件
app.use((req, res, next) => {
    // console.log(req.url);
    if (req.url.startsWith('/lib') || req.url.startsWith('/images')) {
        // 满足条件,说明是静态资源
        // fs.readFile(path.join(__dirname, req.url), (err, data) => {
        //     res.end(data);
        // })
        // sendFile是异步读取文件,并响应读取的结果
        res.sendFile(__dirname + '/manager' + decodeURIComponent(req.url));
    } else {
        // 不满足条件,交给下一个中间件,否则服务器会卡住
        next();
    }
});

app.get('/index.html', (req, res) => {
    res.sendFile(__dirname + '/manager' + decodeURIComponent(req.url));
});

app.get('/time', (req, res) => {
    res.send(Date.now() + '');
});
实例

03-自定义中间件处理静态资源文件.js

const fs = require('fs');
const express = require('express');
const app = express();
app.listen(3000, () => console.log('又开启了'));

// 自定义中间件,处理静态资源文件
app.use((req, res, next) => {
    console.log(req.url);
    if (req.url.startsWith('/lib') || req.url.startsWith('/images')) {
        res.sendFile(__dirname + '/manager' + decodeURIComponent(req.url));
    } else {
        next(); // 调用next函数,表示当前的中间件处理完毕,代码向后执行即可
    }
});

app.get('/index.html', (req, res) => {
    res.sendFile(__dirname + '/manager' + decodeURIComponent(req.url));
});

app.get('/time', (req, res) => {
    res.send(Date.now() + '');
});

方案二:

app.use([请求的url的开头部分], 中间件函数);

const fs = require('fs');
const express = require('express');
const app = express();
app.listen(3000, () => console.log('又开启了'));

// 自定义中间件,处理静态资源文件
app.use('/lib', (req, res, next) => {
    console.log(req.url); // 这里req.url不再包含 /lib 了
    res.sendFile(__dirname + '/manager/lib' + decodeURIComponent(req.url));
});

app.use('/images', (req, res, next) => {
    res.sendFile(__dirname + '/manager/images' + decodeURIComponent(req.url));
});

app.get('/index.html', (req, res) => {
    res.sendFile(__dirname + '/manager' + decodeURIComponent(req.url));
});

app.get('/time', (req, res) => {
    res.send(Date.now() + '');
});
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
var createError = require('http-errors'); var express = require('express'); var path = require('path'); var cookieParser = require('cookie-parser'); var logger = require('morgan'); var indexRouter = require('./routes/index'); var usersRouter = require('./routes/users'); const UserRouter = require('./routes/admin/UserRouter'); const JWT = require('./util/JWT'); const NewsRouter = require('./routes/admin/NewsRouter'); const webNewsRouter = require('./routes/web/NewsRouter'); const ProductRouter = require('./routes/admin/ProductRouter'); var app = express(); // view engine setup app.set('views', path.join(__dirname, 'views')); app.set('view engine', 'jade'); app.use(logger('dev')); app.use(express.json()); app.use(express.urlencoded({ extended: false })); app.use(cookieParser()); app.use(express.static(path.join(__dirname, 'public'))); app.use('/', indexRouter); app.use('/users', usersRouter); app.use(webNewsRouter) /* /adminapi/* - 后台系统用的 /webapi/* - 企业官网用的 */ app.use((req, res, next) => { // 如果token有效 ,next() // 如果token过期了, 返回401错误 if (req.url === "/adminapi/user/login") { next() return; } const token = req.headers["authorization"].split(" ")[1] if (token) { var payload = JWT.verify(token) // console.log(payload) if (payload) { const newToken = JWT.generate({ _id: payload._id, username: payload.username }, "1d") res.header("Authorization", newToken) next() } else { res.status(401).send({ errCode: "-1", errorInfo: "token过期" }) } } }) app.use(UserRouter) app.use(NewsRouter) app.use(ProductRouter) // catch 404 and forward to error handler app.use(function (req, res, next) { next(createError(404)); }); // error handler app.use(function (err, req, res, next) { // set locals, only providing error in development res.locals.message = err.message; res.locals.error = req.app.get('env') === 'development' ? err : {}; // render the error page res.status(err.status || 500); res.render('error'); }); module.exports = app;
07-15
根据你提供的代码,这是一个使用 Express 框架构建的 Node.js 应用程序。它包含了一些中间件和路由处理程序。 首先,它引入了一些依赖包和模块,如 `http-errors`、`express`、`path`、`cookie-parser` 和 `logger`。然后,它引入了一些路由文件,如 `indexRouter`、`usersRouter`、`UserRouter`、`NewsRouter`、`webNewsRouter` 和 `ProductRouter`。 接着,它创建了一个 Express 应用程序实例,并设置了视图引擎为 Jade,并指定了视图文件夹的路径。然后,它使用了一些中间件,如 `logger`、`express.json()`、`express.urlencoded()`、`cookieParser()` 和 `express.static()`,以及指定了静态文件的路径。 接下来,它使用了一些路由处理程序,如 `indexRouter`、`usersRouter`、`webNewsRouter`、`UserRouter`、`NewsRouter` 和 `ProductRouter`。 在这段代码中,有一个自定义中间件函数,它首先检查请求的 URL 是否为 "/adminapi/user/login",如果是,则继续执行下一个中间件或路由处理程序。否则,它会解析请求头中的 Authorization 字段,并验证 JWT 令牌的有效性。如果令牌有效,则生成新的令牌,并将其设置到响应头的 Authorization 字段中,并继续执行下一个中间件或路由处理程序。如果令牌无效或过期,则返回 401 错误。 最后,它定义了一个错误处理中间件,用于捕获 404 错误和其他错误,并将其渲染为错误页面。 整个应用程序通过 `module.exports` 导出,可以在其他文件中引入和使用这个应用程序实例。 这只是你提供的代码的一个概览,如果你有具体的问题或需要更多解释,请告诉我。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值