当前位置:   article > 正文

字节青训前端笔记 | Node 框架(express 和 koa)_koa cookie-parser

koa cookie-parser

书接上文,现在常用的后端框架是 express 和 koa,这里分别给出简单的例子

express

Express是基于nodejs的一个框架,它把原先的许多操作变的简单灵活, 使用Express 可以快速地搭建一个完整功能的网站。express官方网址:www.expressjs.com.cn

  • 引入express

我们首先下载它的依赖,创建一个 app.js 的文件,之后在项目中引入其模块就可以使用express了:

const express = require('express');		//引入express模块
var app=express();
  • 1
  • 2

只要给我们绑定的 express 的提供一个监听的端口就可以启动一个服务:

app.listen(8080);
  • 1

之后使用 node app.js 启动服务

  • Express路由方法

Express路由是用一个方法包裹一个路径,当你收到指定路径的对应方法的请求的时候,调用其回调方法

Express方法源于 HTTP 方法之一。它可请求的方法包括:get、post、put、head、delete、options、trace、copy、lock、mkcol、move、purge、propfind、proppatch、unlock、report、mkactivity、checkout、merge、m-search、notify、subscribe、unsubscribe、patch、search 和 connect。

Express 路径包含三种表达形式,分别为字符串、字符串模式、正则表达式

app.get("/test",function(req,res){
})
app.get("/ab+cd",function(req,res){
})
app.get(/^a/,function(req,res){
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

express 还提供了动态路,当路径匹配到一个模式的路由时,可以获得对应模式的参数,例如:

app.get("/login/:aid",function(req,res){
});
//你可以输入 /login/123  这种模式来匹配它
  • 1
  • 2
  • 3
  • 获得请求参数

我们最常用的接口请求是 get 和 post 他们有不同的参数获取方式

get 请求的数据一般存放在请求路径中,可以通过 query 参数获取

//http://localhost:8080/login?goods1=0001&goods2=0002
app.get("/login",function(req,res){
	console.log(req.query.user);
});
  • 1
  • 2
  • 3
  • 4

post 方法的参数一般在 req.body 中,一般是json格式的数据

//http://localhost:8080/login
app.get("/login",function(req,res){
	console.log(req.body);
});
//{ name:'1111',pwd:'1222'}
  • 1
  • 2
  • 3
  • 4
  • 5

Express中也可以使用 body-parser 作为请求体解析post数据,这个模块也能解析:JSON、Raw、文本、URL-encoded格式的请求体。

const bodyParser=require("body-parser");

// 解析以 application/json 和 application/x-www-form-urlencoded 提交的数据
var jsonParser = bodyParser.json();
var urlencodedParser = bodyParser.urlencoded({ extended: false });

app.post("/",urlencodedParser,function(req,res){
	res.send(req.body);
});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 中间件

中间件是进行中间代理操作的,大多数情况下,中间件就是在做接收到请求和发送响应中间的一系列操作,使用 app.use 可以获得写入应用级别中间键,在访问你的回调函数之前,你可以不通过路径使得全部的接口都调用你的中间键,或者提供一个路径,使得对应路径的接口才触发你的中间键,中间键可以拿到接口的参数信息等,也可以直接进行返回,其中有一个next是使得它进行下一步操作的方法

app.use((err, req, res, next) =>{
	console.log("访问之前");
	next();
});
app.use("/user",function(err,req,res,next){
	console.log("用户登录");
	next(err);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

路由级中间件和应用级中间件类似,不同的是它触发的位置是路由匹配之前,而后者是路由匹配之后

var router = express.Router()
router.use("/",(err, req, res, next) =>{
	console.log("匹配前");
	next();
});
  • 1
  • 2
  • 3
  • 4
  • 5

express.static 是 Express的唯一内置中间件。通过express.static我们可以指定要加载的静态资源。root代表加载静态资源的路径,options作为可选参数可以配置属性,具体可以查阅官方文档

  • cookie和session

浏览器会将我们的操作信息保存到cookie上面。进而言之,cookie就是储存在用户本地终端上的数据。你可以通过express 在接口中可以设置和获取cookie

const cookieParser=require("cookie-parser");
app.use(cookieParser());
//设置cookie
app.get("/set",function(req,res){
	res.cookie("userName",'张三',{maxAge: 20000, httpOnly: true});
	res.send("设置cookie成功");
});

//获取cookie
app.get("/get",function(req,res){
	console.log(req.cookies.userName);
	res.send("获取cookie成功,cookie为:"+ req.cookies.userName);
});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

session是另一种记录客户状态的机制,与cookie保存在客户端浏览器不同,session保存在服务器当中,当客户端访问服务器时,服务器会生成一个session对象,对象中保存的是key:value值,同时服务器会将key传回给客户端的cookie当中;当用户第二次访问服务器时,就会把cookie当中的key传回到服务器中,最后服务器会吧value值返回给客户端。

const session=require("express-session");
app.use(session({
	 secret: "keyboard cat",
	 resave: false,
	 saveUninitialized: true,
	 cookie: ('name', 'value',{maxAge:  5*60*1000,secure: false})
}));
app.use('/login',function(req,res){
	//设置session
	req.session.userinfo='张三';
    //获得session
    console.log(req.session.userinfo)
    //销毁session
	req.session.destroy(function(err){
	})
});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

seesion的配置项如下:

1. name - cookie的名字(原属性名为 key)。(默认:’connect.sid’)
2. store - session存储实例
3. secret - 用它来对session cookie签名,防止篡改
4. cookie - session cookie设置 (默认:{ path: ‘/‘, httpOnly: true,secure: false, maxAge: null })
5. genid - 生成新session ID的函数 (默认使用uid2库)
6. rolling - 在每次请求时强行设置cookie,这将重置cookie过期时间(默认:false)
7. resave - 强制保存session即使它并没有变化 (默认: true, 建议设为:false)
8. proxy - 当设置了secure cookies(通过”x-forwarded-proto” header )时信任反向代理。当设定为true时,
”x-forwarded-proto” header 将被使用。当设定为false时,所有headers将被忽略。当该属性没有被设定时,将使用Express的trust proxy。
9. saveUninitialized - 强制将未初始化的session存储。当新建了一个session且未设定属性或值时,它就处于未初始化状态。在设定一个cookie前,这对于登陆验证,减轻服务端存储压力,权限控制是有帮助的。(默认:true)
10. unset - 控制req.session是否取消(例如通过 delete,或者将它的值设置为null)。这可以使session保持存储状态但忽略修改或删除的请求(默认:keep)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 连接数据库

一般的,后端需要有连接数据库功能,使得你交互的数据可以持久化,node 可以连接多种不同种类的数据库,这里简单介绍 mysql 数据库的连接,只需要下载一个 mysql 的依赖再配置数据库就可以运行了:

const mysql = require("mysql");
var db=mysql.createConnection({host: "localhost",  //地址 
							port: "3306",          //端口
							user: "root",          //用户名
							password: "123456",    //密码
							database: "test"}); //数据库名称
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

我们可以通过 query 语句提交 sql 语句来执行操作,之后通过回调函数来处理结果,以下是一个简单的例子,假设我们传入 name 和 pwd字段,我们通过模板字符串拼接成一个完整的sql语句,然后执行它:

db.query(`INSERT INTO students (name,pwd) VALUES('${req.query.name}','${req.query.pwd}')`,function(err,data){
			if(err){
				res.status(500).send('创建失败').end();
			}else{
				res.status(200).send('创建成功').end();
            }
});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 上传文件

node 除了可以操作数据库,也可以对服务器上的文件进行操作,通过 multer 可以帮助我们快速处理文件类型的数据,我们只需要引入他,然后配置文件存放的地址,最后配置它即可

const multer=require('multer');
var upload=multer({dest:'./upload/'});  //dest是文件存放的路径
var fs = require('fs');
const singleMidle = upload.single("singleFile"); //一次处理一张,参数的名字是你type="file"组件的name字段
const arrMidle  = upload.array("arrayFile", 5);//一次最多处理5张
const fieldsMidle  = upload.fields([
  {name:"fieldSingleFile", maxCount:1},
  {name:"fieldArrayFile", maxCount:4}
]);//可同时处理多个上传控件的上传

//单个文件的处理
app.use("/",singleMidle,function(req,res,next){
	var oldFile=req.file.destination+req.file.filename;	//指定旧文件
	var newFile=req.file.destination + req.file.originalname;	//指定新文件
	fs.rename(oldFile,newFile,function(err){
		if(err){
			res.send('上传失败!');
		}else{
			res.send('上传成功!');
		}
	});
	next();
});

//这是文件里的上传模块html
<input type="file" name="singleFile" >

//多个文件的处理
app.use("/",arrMidle,function(req,res,next){
	req.files.forEach(function(ele,index){
		console.log(ele);
		var oldFile=ele.destination+ele.filename;	//指定旧文件
		var newFile=ele.destination+ele.originalname;	//指定新文件
		fs.rename(oldFile,newFile,function(err){
			err?console.log('上传失败!'):console.log('上传成功!');
		});
	});
	res.send("成功上传");
});

//这是文件里的上传模块html
<input type="file" name="arrayFile" multiple>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42

Multer通过使用limits这个对象来对数据进行限制

var upload=multer({dest:'./upload/',limits:{fileSize: 1024 * 1024 * 20,files: 5}});
  • 1
  • 下载文件

通过 res.download() 就可以实现服务器上文件的下载:

res.download('/1.pdf');
res.download('/1.pdf', function(err){
});
  • 1
  • 2
  • 3
  • 模板引擎

和大多数后台语言一样,nodejs 可以指定网页渲染的模板引擎。这里简单介绍常用的模板引擎 ejs ,想要具体了解的可以自行查阅文档。

https://ejs.bootcss.com/#docs

我们首先下载依赖,然后创建一个 .ejs 文件,标记<% %>和<%= %>来当做模板,前者是可以包裹一段 js 代码,后者则是可以输出一个对应的值:

<html>
<body>
    <ul>
        <%
            for(var i = 0; i < students.length; i++){
        %>
           <li><%= students[i] %></li>
        <%
            }
        %>
    </ul>
</body>
</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

之后在 app.js 中添加模板引擎相关代码

// 设置模板引擎渲染界面的存放文件夹
app.set('views', path.join(__dirname, 'views'));
//设置模板引擎为ejs
app.set('view engine', 'ejs');

//这个接口告诉我们,当我们访问指定路由的时候,express会找到设定文件夹下方的index.ejs文件,然后使用我们传入的数据来渲染这个界面
app.get("/",(req,res)=>{
    res.render("index",{
        "students" : ["小明","小红","小强"],
    },function(err, html) {
  		console.log(html);//这是渲染完成的html
	}));   
});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

koa

koa是express同一个团队开发的一个新的Web框架,Koa旨在为Web应用程序和API提供更小、更丰富和更强大的能力,以及更强大的异步处理能力。

  • koa的引入

同样,我们只需要下载依赖然后导入它就可以使用我们的 koa 框架

const Koa = require('koa')
const app = new Koa()
  • 1
  • 2
  • 中间件

和 express 一样,koa也提供了中间件的能力,你可以在 koa 框架写入一个函数,这个函数有两个参数,context 指的是上下文环境对象,封装了一些属性,该对象类似原生http中的 req + res,具体的详细属性可以查看官网 https://koajs.com/#context,后续会随着例子简单介绍一些属性;next 用于把中间件的执行权交给下游的中间件,在当前中间件中位于 next() 之后的代码会暂停执行,直到最后一个中间件执行完毕,再自下而上依次执行每个中间件中 next 值周的代码,类似于栈的先进后出。

app.use((ctx, next) => {
  console.log(ctx.request.url); //请求地址
  console.log(ctx.request.method);  //请求方法,GET,POST等
  next()
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 路由

koa 使用了专门的 koa-router 模块来控制路由,你还是需要先下载依赖,其接口的写法和 express 的基本一致

const Koa = require('koa')
const app = new Koa()
const userRouter = require('./routers/users')
// 把返回的函数注册为中间件
app.use(userRouter.routes())
// 捕获不支持的请求,注册为中间件 客户端接收到:405 Method Not Allowed,501 Not Implemented等等
app.use(userRouter.allowedMethods())
app.listen(8000, () => {
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

routers/users.js:

const Router = require('koa-router')
// prefix 前缀
const router = new Router({ prefix: '/users' })

router.get('/', (ctx, next) => {
  //返回状态码
  ctx.response.status = 200
  //返回值
  ctx.response.body = 'test'
})

router.post('/list', (ctx, next) => {
  ctx.response.body = 'list'
})

module.exports = router 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 参数解析

koa 支持解析我们的路径参数,get 的请求参数

//请求地址 http://localhost:8000/users/test?id=1
router.get('/:path', (ctx, next) => { 
  console.log(ctx.request.params); //{ path: 'test' }
  console.log(ctx.request.query); //{ id: 1 }
})
  • 1
  • 2
  • 3
  • 4
  • 5

koa默认没有内置解析post的 jsonurlencoded的中间件,我们还是推荐我们使用 koa-bodyparser

const Koa = require('koa')
const bodyParser = require('koa-bodyparser')
const app = new Koa()

// 使用第三方库帮助解析 json和urlencoded
app.use(bodyParser())

app.use((ctx, next) => {
  console.log('ctx.request.body: ', ctx.request.body);  //body是post传递参数的位置
  next()
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 文件和静态资源

koa 有 koa-multer 这个库来是实现文件上传,其用法和 express 的基本一致,如果想使用express 的static 这个库的,express需要额外下载模块 koa-static

const koaStatic = require('koa-static')
const app = new Koa()
app.use(koaStatic('./dist'))
  • 1
  • 2
  • 3
  • 数据库和模板引擎

数据库的连接操作和 express 完全一致,因为连接数据库使用的是独立的包,express 和 koa 仅仅在编写接口处理逻辑时有所不同,数据库的操作全部依赖 mysql 这个模块进行操作,所以完全一致,不再赘述;模板引擎相关的操作涉及到代码逻辑部分 express 和 koa也完全一致,所以也不再赘述

  • 异常处理

与 express 不同的是,express 中的操作的回调函数中,都会有一个 err 选项,你可以从中接收错误进行处理;koa中你可以使用 try catch的语法来进行错误的捕捉,使用 app.on 监听异常可以捕获到抛出的异常进行处理

router.post('/list', (ctx, next) => {
 	    try{
        //.....
        }catch(error){
            error.message = '异常代码101';
            throw error;    // 抛出处理后的异常
        }
	}
})
app.on('error', err =>  
    log.error('server error', err)  
);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

后续可能会更新一个 express 相关项目,先放出 git 地址:https://github.com/aiai0603/nodejs_work

两者的对比

根据上文可以看出,express 和 koa 基本上用法是没有太大的差异的,但是前文说过,koa 在异步处理和性能上更加优秀,这里简单谈谈两者的区别和其产生的原因:

  1. 异步和错误处理上:

Express是基于回调进行处理,也是node中最常见的 Error-First 的模式,操作的回调函数中,都会有一个 err 选项,

Koa是使用的号称异步终极解决方案的Async/Await,也就是基于Promise 进行异步的处理,所以可以使用Try-Catch来捕获错误

  1. 中间件的区别

Express的中间件是线性模型:中间件一个接一个按照顺序执行,上一个中间件会通过next触发下一个中间件,response响应写在最后一个中间件中,遇到http请求,根据path和method判断触发哪些中间件;

Koa的中间件是洋葱模型,通过async await实现的,中间件之间通过next函数联系,当一个中间件调用next()后,会将控制权交给下一个中间件,直到下一个中间件不再执行next()后,会沿路返回,将控制权交给前一个中间件。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/164861
推荐阅读
相关标签
  

闽ICP备14008679号