赞
踩
书接上文,现在常用的后端框架是 express 和 koa,这里分别给出简单的例子
Express是基于nodejs的一个框架,它把原先的许多操作变的简单灵活, 使用Express 可以快速地搭建一个完整功能的网站。express官方网址:www.expressjs.com.cn
我们首先下载它的依赖,创建一个 app.js 的文件,之后在项目中引入其模块就可以使用express了:
const express = require('express'); //引入express模块
var app=express();
只要给我们绑定的 express 的提供一个监听的端口就可以启动一个服务:
app.listen(8080);
之后使用 node app.js
启动服务
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){
})
express 还提供了动态路,当路径匹配到一个模式的路由时,可以获得对应模式的参数,例如:
app.get("/login/:aid",function(req,res){
});
//你可以输入 /login/123 这种模式来匹配它
我们最常用的接口请求是 get 和 post 他们有不同的参数获取方式
get 请求的数据一般存放在请求路径中,可以通过 query 参数获取
//http://localhost:8080/login?goods1=0001&goods2=0002
app.get("/login",function(req,res){
console.log(req.query.user);
});
post 方法的参数一般在 req.body 中,一般是json格式的数据
//http://localhost:8080/login
app.get("/login",function(req,res){
console.log(req.body);
});
//{ name:'1111',pwd:'1222'}
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);
});
中间件是进行中间代理操作的,大多数情况下,中间件就是在做接收到请求和发送响应中间的一系列操作,使用 app.use 可以获得写入应用级别中间键,在访问你的回调函数之前,你可以不通过路径使得全部的接口都调用你的中间键,或者提供一个路径,使得对应路径的接口才触发你的中间键,中间键可以拿到接口的参数信息等,也可以直接进行返回,其中有一个next是使得它进行下一步操作的方法
app.use((err, req, res, next) =>{
console.log("访问之前");
next();
});
app.use("/user",function(err,req,res,next){
console.log("用户登录");
next(err);
}
路由级中间件和应用级中间件类似,不同的是它触发的位置是路由匹配之前,而后者是路由匹配之后
var router = express.Router()
router.use("/",(err, req, res, next) =>{
console.log("匹配前");
next();
});
express.static 是 Express的唯一内置中间件。通过express.static我们可以指定要加载的静态资源。root代表加载静态资源的路径,options作为可选参数可以配置属性,具体可以查阅官方文档
浏览器会将我们的操作信息保存到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);
});
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){
})
});
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)
一般的,后端需要有连接数据库功能,使得你交互的数据可以持久化,node 可以连接多种不同种类的数据库,这里简单介绍 mysql 数据库的连接,只需要下载一个 mysql 的依赖再配置数据库就可以运行了:
const mysql = require("mysql");
var db=mysql.createConnection({host: "localhost", //地址
port: "3306", //端口
user: "root", //用户名
password: "123456", //密码
database: "test"}); //数据库名称
我们可以通过 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();
}
});
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>
Multer通过使用limits这个对象来对数据进行限制
var upload=multer({dest:'./upload/',limits:{fileSize: 1024 * 1024 * 20,files: 5}});
通过 res.download() 就可以实现服务器上文件的下载:
res.download('/1.pdf');
res.download('/1.pdf', function(err){
});
和大多数后台语言一样,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>
之后在 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
}));
});
koa是express同一个团队开发的一个新的Web框架,Koa旨在为Web应用程序和API提供更小、更丰富和更强大的能力,以及更强大的异步处理能力。
同样,我们只需要下载依赖然后导入它就可以使用我们的 koa 框架
const Koa = require('koa')
const app = new Koa()
和 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()
})
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, () => {
})
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
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 }
})
koa默认没有内置解析post的 json
和urlencoded
的中间件,我们还是推荐我们使用 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()
})
koa 有 koa-multer
这个库来是实现文件上传,其用法和 express 的基本一致,如果想使用express 的static 这个库的,express需要额外下载模块 koa-static
const koaStatic = require('koa-static')
const app = new Koa()
app.use(koaStatic('./dist'))
数据库的连接操作和 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)
);
后续可能会更新一个 express 相关项目,先放出 git 地址:https://github.com/aiai0603/nodejs_work
根据上文可以看出,express 和 koa 基本上用法是没有太大的差异的,但是前文说过,koa 在异步处理和性能上更加优秀,这里简单谈谈两者的区别和其产生的原因:
Express是基于回调进行处理,也是node中最常见的 Error-First
的模式,操作的回调函数中,都会有一个 err 选项,
Koa是使用的号称异步终极解决方案的Async/Await
,也就是基于Promise 进行异步的处理,所以可以使用Try-Catch来捕获错误
Express的中间件是线性模型:中间件一个接一个按照顺序执行,上一个中间件会通过next触发下一个中间件,response响应写在最后一个中间件中,遇到http请求,根据path和method判断触发哪些中间件;
Koa的中间件是洋葱模型,通过async await实现的,中间件之间通过next函数联系,当一个中间件调用next()后,会将控制权交给下一个中间件,直到下一个中间件不再执行next()后,会沿路返回,将控制权交给前一个中间件。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。