node入门(五) - express(中间件,路由,文件上传,虚拟主机)

本文详细介绍Express.js的基础使用方法,包括安装、配置、路由处理及中间件应用等内容。同时介绍了如何利用Express.js处理常见HTTP请求、文件上传及会话管理。

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

环境

官方文档地址:

http://www.expressjs.com.cn/4x/api.html

IEDA
第一种方式(直接安装):
npm install express
npm init(生成package.json文件) 一直按回车
npm install ejs


第二种方式(安装生成器):
安装express生成器
npm install express-generator -g
命令行 express -h
**这是命令行输出**
 -h, --help           output usage information
     --version        output the version number
 -e, --ejs            add ejs engine support
     --pug            add pug engine support
     --hbs            add handlebars engine support
 -H, --hogan          add hogan.js engine support
 -v, --view <engine>  add view <engine> support  (ejs|hbs|hjs|jade|pug|twig|vash) (defaults to jade)
-c, --css <engine>   add stylesheet <engine> support (less|stylus|compass|sass) (defaults to plain css)
    --git            add .gitignore
-f, --force          force on non-empty directory

-v 代表视图模板,默认jade(很难用)
-c 代表css(可选less/sass)
//hbs 就是handlebars

安装模板实例(可根据项目安装不同模板):
一种方式: 
express . 不推荐
y

另一种指定模板
express -v hbs -c less
express -v ejs -c sass
最后:
npm install 安装依赖

入门demo(基于第一种安装方式)

项目结构
node_modules/     ---包依赖
router/           ---路由
    index.js
    user.js
views/            ---视图
    index.ejs     ---模板文件
testExpress.js    ---入口

testExpress.js(默认其实是app.js)

"use strict";

var express = require('express');
var app = express();

/**router处理全部东西
* app.use(require('./router/index'));
* 处理以/开始的
* app.get(post,use,all,...)
*/
app.all('/',require('./router/index'));
app.all('/user',require('./router/user'));

app.listen(3000, function () {
    console.log('服务器启动了');
});

index.js中添加操作

通过express的Router(),得到路由。Router 实例是一个完整的中间件和路由系统
router上基本的delete,post,get,put..等。都存在,内有三个参数
分别是:
req : 请求
resp : 响应方法
包含以下方法

|方法                     |描述
res.download()           |提示下载文件。
res.end()                |终结响应处理流程。
res.json()               |发送一个 JSON 格式的响应。
res.jsonp()              |发送一个支持 JSONP 的 JSON 格式的响应。
res.redirect()           |重定向请求。
res.render()             |渲染视图模板。
res.send()               |发送各种类型的响应。
res.sendFile             |以八位字节流的形式发送文件。
res.sendStatus()         |设置响应状态代码,并将其以字符串形式作为响应体的一部分发送。

next : 用于中间件处理数据
'use strict'

var express = require('express');

var router = module.exports = express.Router();

router.get('/',function (req,resp,next) {
    // 可以通过next添加中间处理,比如权限之类
    console.log('这是中间件1');
    next();
},function (req,resp,next) {
    var data ={id:23,name:'这是一个张三'};
    // resp.send('我在处理/开始的');
    //render表示到哪个视图
    resp.render('index.ejs',{data:data});
});

// 也可以使用下面方式处理
router.get('/',function (req,resp,next) {
    // 可以通过next添加中间处理,比如权限之类
    console.log('这是中间件1');
    next();
});
router.get('/',function (req,resp,next) {
    var data ={id:23,name:'这是一个张三'};
    // resp.send('我在处理/开始的');
    //render表示到哪个视图
    resp.render('index.ejs',{data:data});
});

index.ejs将携带数据处理

ejs模板本身语法和jsp一样,这里就不详细说明
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <% for(var i =0 ;i<10;i++){%>
    ID : <%=data.id%><br/>
    姓名 : <%=data.name%>
    <%}%>
</body>
</html>

user.js

'use strict'

var express = require('express');

var router = module.exports = express.Router();

router.get('/user',function (req,resp) {
    resp.send('我在处理user');
});

基于express生成器(第二种方式)

项目结构
node_modules/     ---包依赖
router/           ---路由
    index.js
    user.js
    file.js
util/             ---工具类
    cookie-session.js -- 会话session
views/            ---视图
    index.hbs     ---模板文件
    error.hbs
    file.hbs
    form.hbs
    layout.hbs
app.js    ---入口
监视目录、替换node
npm install supervisor -g(g代表全局)
cmd 命令行 %appData% (npm默认目录)如下图

一旦更新js, Ctrl+s 自动更新

配置图(基于IDEA)

npm目录

配置idea运行

构成

中间件、路由、视图(模板引擎,在下章介绍)
项目结构

中间件与路由

app、express.Router()

use([path],cb)、all(path,cb)、get()、post()、……(支持8种请求方式)
callback([err]、req、resp、next)、next()

app.js中

var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
//得到路由
var index = require('./routes/index');
var users = require('./routes/users');
var file = require('./routes/file');
var help = require('./routes/help');

var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'hbs');

// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());//处理body
app.use(bodyParser.urlencoded({ extended: false }));//处理编码
app.use(cookieParser());//处理cookie
app.use(require('less-middleware')(path.join(__dirname, 'public')));//处理less
app.use(express.static(path.join(__dirname, 'public')));//处理public的静态网页

//处理路由
app.use('/', index);
app.use('/users', users);
app.use('/file', file);
app.use('/help', help);

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  var err = new Error('Not Found');
  err.status = 404;
  next(err);
});

/** error handler
 * 错误页:回调函数,需要四个参数
 * @callback([err]、req、resp、next)、next()
 * @path : 代表页面url
 * 回调 : 四个参数
 *   @err:错误,req:请求,resp:返回
 *   @next:用处,可以在页面跳转之前,执行其他操作,比如添加插件
 */
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');
});

Request 方法

params、query、body、 cookies、 path
app、method、hostname、ip、originalUrl

 /** Request
 *  @req.params 配合router得到后面的匿名参数
 *      /:x(\\d+)/:y(\\w+) 后面是正则,实现动态参数
 *  @req.query 得到表单提交的数据 -- get处理方式
 *  @req.body 得到表单提交数据post
 *  @req.cookies 得到客户端发送的cookies
 *  @req.path 当前path,router.all()后第一个参数
 *  @req.app 当前的app
 *  @req.method 当前的请求方式
 *  @req.hostname 当前的主机名
 *  @req.ip 当前的ip
 *  @req.originalUrl 原始的url
 */

form.hbs

<form method="post">
    账户: <input type="text" name="name" id=""><br>
    密码: <input type="password" name="password"><br>
    <button>发送</button>
</form>

在index.js中

在地址栏输入访问
// http://localhost:3000/1/abc

// 得到后面的匿名参数
router.get('/:x(\\d+)/:y(\\w+)', function (req, resp, next) {
    console.error(req.params);//{ x: '1', y: 'abc' }
    resp.send(req.params);
}
// 得到get请求参数和cookies
router.get('/', function (req, resp, next) {
    console.error(req.query);//得到get请求参数
    console.error(req.cookies);//得到cookies
    console.error(req.path);// /
    console.error(req.app);
    console.error(req.method);// GET
    console.error(req.hostname);// localhost
    console.error(req.ip);// ::1
    console.error(req.originalUrl);// /
    resp.render('form',{title:'测试'});
}
// 得到post请求参数和cookies
router.post('/', function (req, resp, next) {
    console.error(req.body);// 得到post请求参数
    console.error(req.cookies);//得到cookies
    console.error(req.path);// /
    console.error(req.app);
    console.error(req.method);// POST
    console.error(req.hostname);// localhost
    console.error(req.ip);// ::1
    console.error(req.originalUrl);// /
}

Responset方法

send()、render()、json()、jsonp()、redirect()
type()、set()

/** Response
*   @resp.send(data) 将数据发送到页面,也可以是html
*   @resp.render('modules',data) 前一个参数是跳转view下的页面 后一个参数时携带的数据
*   @resp.json({}) 发送json数据
*   @resp.jsonp({}) 实现跨域请求
*   @resp.redirect() 重定向
*   @resp.type('类型') 默认text/html 可以设置为普通文本text/plain
*   @resp.set(,) 如果编码错误可以使用
 */

在index.js中

// 如果要测试,记得注释多余的resp代码
router.get('/', function (req, resp, next) {
    console.error(req.query);

    resp.send({name: 'zhangsan'});
    resp.json({name: 'zhangsansan'});
    //hbs 语法后面会讲
    resp.render('form',{data:'sanzhangsan'});
    resp.redirect('index');
    /* jsonp,然后将地址栏改为http://localhost:3000/?callback=xx,再次看页面效果。跨域处理方案
    */
    resp.jsonp({name: 'zhangsansan'});
    // 默认是text/html 需要以纯文本解析就设置type
    resp.type('text/plain');
    resp.send('<h1>Hello World</h1>');
    //如果想要设置更多头
     resp.set({
        'Content-Type': 'text/plain',
        'Content-Length': '123',
        'ETag': '12345'
    });
    resp.send('<h1>Hello World</h1>');
});

cookie-session

npm install cookie-session -S

将cookie-session设置为工具类,首先新建util目录,然后新建cookie-session.js文件

在cookie-session.js文件

const KEYS =['QAQA','cbabc','lisi'];
/**
* cookie-session就是个函数
* 中必定配置的项目是keys(加密秘钥)
* cookie会话session
* 在浏览器Application cookies中查看
*       session以base64储存,session.sig是session校验
* cookie会话session
* */
module.exports = exports = {
    cookieSession : require('cookie-session')({
        name: 'session',
        keys: KEYS,
        // Cookie Options
        maxAge: 24 * 60 * 60 * 1000 // 24 hours
    })
};

router/users.js中

var express = require('express');
var router = module.exports = express.Router();
var cookieSession = require('../util/cookie-session').cookieSession;

//代表文件下全部都要使用session
router.use(cookieSession);
/**
 *  仅仅是一个文件要使用,就用下面注释的方法
 * */
// router.all('/',cookieSession ,function (req, res) {
router.get('/',function (req, res) {
    console.error(req.session);
    res.send('<h1>得到session</h1>');
});

//设置session
router.get('/set',function (req, res) {
    req.session.userId = 5;
    req.session.userName = '张三';
    res.send('<h1>设置session</h1>');
});

//删除session的userId
router.get('/del',function (req, res) {
    delete req.session.userId;
    // delete req.session.userName;
    res.send('<h1>删除session</h1>');
});
//删除session的全部
router.get('/delall',function (req, res) {
    req.session = null;
    res.send('<h1>删除全部session</h1>');
});
如果需要将其配置在app以中间件使用,参考文档

https://npm.taobao.org/package/cookie-session

文件上传

npm install connect-multipart -S 

用法:
connect-multiparty({maxFieldsSize、maxFilesSize、encoding})

参数:
maxFieldsSize:所有文件何在一起的大小
maxFilesSize:一个文件最大大小(若为多文件上传)
encoding:文件的编码 

在views\file.hbs中

<h1>{{title}}</h1>
<!--
文件上传必须是post,设置enctype="multipart/form-data"
-->
<form action="" method="post" enctype="multipart/form-data">
    <input type="file" name="file"><br>
    <button type="submit">提交</button>
</form>

routes\file.js中配置路由

var express = require('express');
var router = module.exports = express.Router();
// 仅仅做测试就不设置参数
var upload = require('connect-multiparty')();
var fs = require('fs');

/*
get 访问views\file.hbs,携带数据title
*/
router.get('/', function (req, res) {
    console.error(req.path);
    res.render('file',{title:'测试文件上传'});
});
/*
post 用于文件上传操作
*/
router.post('/', upload, function (req, res) {
    // req.files 得到上传文件的临时文件名
    console.error(req.files.file.path);
    // 重定向,防止用户重复提交
    res.redirect('file');
    // 创建输入流
    var readStream = fs.createReadStream(req.files.file.path);
    var name = new Date().getTime();
    //通过内置fs模块读入文件
    var writeStream = fs.createWriteStream( __dirname +"/../public/images/"+name+".jpg");
    readStream.pipe(writeStream);
    // 注册异步事件
    readStream.on('end', function () {
        fs.unlinkSync(req.files.file.path);
    });
});

vhost(‘host’)

npm install vhost 虚拟主机
同一台电脑上的不同ip/域名绑定不同的服务,类似与PhpStudy里面的站点域名管理,新增不同的ip地址。
var vhost = require('vhost');

/*虚拟主机 node一般配合Nginx使用。此处做了解
 * http://127.0.0.2:3000/ 进行访问
 * */
app.use(vhost('127.0.0.1',function (req,resp) {
  resp.end('123123');
}));
app.use(vhost('127.0.0.2',function (req,resp) {
  resp.end('aadasd');
}));
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值