Node.js Express 框架

Posted ---空白---

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Node.js Express 框架相关的知识,希望对你有一定的参考价值。

1..Express介绍

Express 是一个简洁而灵活的 node.js Web应用框架, 提供了一系列强大特性帮助你创建各种 Web 应用,和丰富的 HTTP 工具。

Express的特点:

  • 实现了路由功能
  • 中间件功能
  • 扩展了req和res对象
  • 可以集成其他模版引擎

Express的安装:

npm i express -S

2.基本实例

使用express搭建一个基本的服务器:
步骤一:引入express
步骤二:创建服务对象 express()
步骤三:设置路由,根据路径给客户端响应相关的数据
步骤四:开启服务

//引入express
const express = require("express")
//创建服务对象
let app = express()

//设置路由,监听根路径的访问
app.get("/",function(req,res){
    res.send("<h1>这是首页</h1>")
})

//开启服务,监听80端口
var server = app.listen(80,function(){
    //当前当前监听的端口号
    var port = server.address().port
    console.log(`Server running at http://127.0.0.1:${port}/`)
})

2.向客户端响应数据

使用res.send()可以向客户端响应数据时,他有以下几个特点:
(1)除了能接收字符串和Buffer,还可以接收数组或者对象
(2)会自动发送更多的响应报文头,无需手动设置Content-type
(3)响应数据的同时内部会调用red.end()方法结束此次响应,当前也意味着res.send()只能发送一次

//发送数组给客户端
res.send([0,1,2,3])

//发送对象给客户端
res.send({name:"雍正",age:45})

与res.end()的对比:
(1)res.end()需要设置Content-type,不然无法正确解析数据
(2)res.end()只能接收字符串和Buffer,其他类型的数据会报错

3.注册路由

注册路由有3种方法,get()/use()/all()
(1)app.get():只接收客户端get方式提交的请求,且路径必须一致。(忽略query参数)
(2)app.use():不限定请求的方法,get/post等都可以。路径模糊匹配,这个路径和他的子路径都可以匹配。
PS:这个特性可以用来搭建静态资源服务器。因为静态资源的路径成千上万,不可能使用get()方式穷举
(3)app.post():只接收客户端post方式提交的请求,且路径必须一致。
(4)app.all():不限定请求的方法,但是请求路径要求严格匹配。

语法:app.get()
参数一:要匹配的路径,可以是字符串,也可以是正则表达式。
参数二:回调函数。回调函数有两个参数req和res,用于获取请求信息和响应数据

app.get("/",function(req,res){
    //获取用户请求的路径
    var url = req.url
    res.send(`当前请求的路径为: ${url}`)
}

4.获取客户端get方式提交的参数

req.query和req.params可以获取到客户端get方式提交的参数

(1)get方式提交参数的方式分为query方式和params方式两种。
在路径后面拼接 ?key1=val1&key2=val2 的方式被称为 query传参。例如:

http://127.0.0.1/process_get?year=2019&mouth=12&day=13 
app.get("/process_get",function(req,res){
    console.log(req.query.year)//2019
    console.log(req.query.mouth)//12
    console.log(req.query.day)//13
    res.send("欢迎访问get提交页面")
})

(2)而通过设置占位符 ,将原本属于路径的信息截取下来的成为params传参。这个方式需要注册路由的时候设置占位符,例如:

http://127.0.0.1/date/2012/12/12
app.get("/date/:year/:mouth/:day",function(req,res){
    console.log(req.params.year)//2012
    console.log(req.params.mouth)//10
    console.log(req.params.day)//13
    res.send(\'欢迎访问params页面\')
})

5.读取文件并返回给客户端

res.sendFile(path)和res.render(path,data)都可以读取文件并返回给客户端。

区别:
res.sendFile()不能对文件里面的模版代码进行替换,所以不适合渲染模版文件。只适合渲染静态文件
res.render()可以渲染模版文件,但是必须为其配置一个模版引擎,不然默认情况下无法使用。

res.sendFile()的用法:

app.get("/",function(req,res){
    res.sendFile(path.join(__dirname,"index.html"))
})

res.render()的用法(搭配ejs模版引擎)
步骤一:安装模版引擎 npm i ejs
步骤二:在入口文件引入模版引擎
步骤三:声明模版文件的根目录 app.set(\'views\',模版目录)
步骤四:声明使用的模版引擎app.set(\'view engine\',模版引擎)
步骤五:渲染模版文件 res.render(path,data)

安装ejs

npm install ejs

引入模版引擎,并进行相关声明

//入口文件

//引入ejs
const ejs = require(\'ejs\');

//1.创建服务对象
var app = express();

//声明模版文件的目录
app.set(\'views\', \'./public\');
//声明使用的模版引擎
app.set(\'view engine\', ejs);

渲染模版文件并返回给客户端

var news = {
    title:"我是标题",
    content:"我是内容",
    author:"我是作者"
}
//news页面
app.get("/news",function(req,res){
    res.render("news.ejs",news)
})

模版文件(news.ejs)

<!-- 模版文件 -->
<body>
    <h3><%= title %></h3>
    <p><%= content %></p>
    <p><%= author %></p>
</body>

6.静态资源托管服务

express.static()可以进行静态资源托管服务,一般与app.use()注册路由搭配使用

参数一:静态资源的根目录

//加载express
const express = require(\'express\');
const path = require(\'path\');

//1.创建服务对象
var app = express();

//访问/static下的路径视为访问静态资源 http://example.com/static/3.png => public/3.png
app.use(\'/static\', express.static(path.join(__dirname,\'public\')));

//启动服务
app.listen(8080,function(){
    console.log(\'http://localhost:8080\');
})

设置多个根目录(当 public目录中找不到 资源文件时会接着去public2找)

app.use(\'/static\', express.static(path.join(__dirname,\'public\')));
app.use(\'/static\', express.static(path.join(__dirname,\'public2\')));

7.封装路由模块

在实际开发项目中不可能把所有的代码都写入到入口文件中,而是要进行模块化,有利于方便代码管理、项目维护。

PS:我们之前注册路由都是通过app这个对象来完成的,按照这个思路,要封装一个路由模块,就必须接收 app这个参数,拿到这个参数后才能进行下面的路由注册操作。但是从安全的角度不建议这样做,因为这个模版可以拿app这个对象做些注册路由以外的事情,所以这个方法行不通。node.js有专门的API用来解决这个问题,既能注册路由,又不会污染全局。

express.Router()既是一个对象也是一个函数。它可以用来注册路由,使用方法和app.get()一致。

步骤一:新建rouetr.js文件
步骤二:引入express
步骤三:获取express.Router()
步骤四:注册路由,并向外暴漏出这个对象
步骤五:在入口文件中引入router.js模块,并设置成每次用户访问就执行router模块

//router.js

const express = require(\'express\');
//express.Router()既是一个对象也是一个函数
var router = express.Router();

router.get(\'/\',function(req,res){

})
router.get(\'/item\',function(req,res){
    
})
router.get(\'/submit\',function(req,res){
    
})
router.get(\'/add\',function(req,res){
    
})
router.post(\'/\',function(req,res){
    
})
module.exports=router;
//入口文件

//加载express
const express = require(\'express\');
const router = require(\'./router.js\');

//1.创建服务对象
var app = express();

//每次访问都执行router
app.use(\'/\',router);
//如果监听的是根目录,路径可以省略不写,等价于
//app.use(router);

//启动服务
app.listen(8080,function(){
    console.log(\'http://localhost:8080\');
})

8.获取post方式提交的数据

post方式提交的数据存放到请求体中,不在请求头。要解析请求体的数据,需要用到中间件 body-parse

安装body-parse,并引入入口文件中,进行相应的配置后,req会多出一个属性req.body。
post方式提交的数据就存放在req.body中

安装body-parse

npm install body-parse

引入 body-parse 进行相应的配置,之后就可以使用res.body来获取post方式提交的数据了

var app = express()
var bodyParser = require(\'body-parser\')

var app = express()

// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))
// parse application/json
app.use(bodyParser.json())

app.post("/process_post",function(req,res){
    res.send("欢迎访问post提交页面")
    console.log(req.body)
})

控制台打印出:

{year:\'2019\',mouth:\'10\',day:\'13\'}

9.文件上传

文件上传需要用到bodyParser和multer中间件

安装引入中间件后req会多出两个属性req.body和req.file/req.files
single(fileName):如果上传单个文件,则调用这个方法,参数为自定义的文件名。使用req.file可以读取到这个文件的信息
array():如果上传多个文件,则调用这个方法,使用req.files[index]可以读取到这个文件的信息

req.file常用属性:
fieldname:自定义的文件名
originalname 上传时的文件的名称
path:已上传文件的完整路径(临时存放区)

//引入中间件
var bodyParser = require(\'body-parser\');
var multer  = require(\'multer\');

//配置中间件
app.use(bodyParser.urlencoded({ extended: false }));
var storage = multer.diskStorage({
    //设置存放的目录
   destination: function (req, file, cb) {
      cb(null, \'./uploads\')
   },
    //设置文件名
   filename: function (req, file, cb) {
      //获取后缀名
      const extname = file.originalname.split(\'.\').pop();
      cb(null, file.fieldname + \'-\' + Date.now() + extname)
   }
})
//只有在访问这个路径时才保存文件
app.post(\'/file_upload\',multer({ storage: storage }).single(\'image\'), function (req, res) {
   res.send(\'ok\')
})})

中间件 formidable
作用:前面的方法保存上传的文件还需要自己操作fs模块,可以使用一个更方便的中间件来保存上传的问题。
使用这个中间件可以获取到表单中的参数和上传的文件

安装 formidable

npm i -S formidable
//引入formidable
var formidable = require(\'formidable\')
//监听路由
app.post(\'/file_upload\', function (req, res) { 
   console.log(\'接收到请求\')
   //创建实例
   var form = new formidable.IncomingForm();
   //设置上传文件存放的目录
   form.uploadDir = "./uploads"
   //保持原来的文件的扩展名
   form.keepExtensions = true;
   console.log(\'开始解析表单\')
   //解析表单(异步方法)
   form.parse(req, function(err, fields, files) {
      console.log(\'解析表单中\')
      //返回文件信息
      console.log(fields, files)
      // res.send(util.inspect({fields: fields, files: files}))
    });
    console.log(\'解析表单结束\')
    res.send("ok")
})

文件上传后会自动在uploads文件夹中保存一份,只不过文件名是随机生成的

form.parse()中回调函数的参数说明:
fields:非文件信息,例如name,age之类的参数
files:上传的文件信息,具体信息可查看图片。(上传时保存的文件名是随机的,可以通过files.fileUpload.path路径重新访问该文件)

以上是关于Node.js Express 框架的主要内容,如果未能解决你的问题,请参考以下文章

node.js安装使用express框架

Node.js Express框架 详细总结

node.js express mvc轻量级框架实践

配置node.js中的express框架

Node js之Express初步介绍和安装

Node.js Express 框架