Express
安装
可以参考Express官方文档
首先express环境

编写配置文件index.js,并执行
处理请求
处理GET请求:配合req.query
处理POST请求:需要body-parser模块,配合req.body
| GET | POST | JSONP | COOKIE |
|---|
req.query | req.body | req.query | req.cookies |
//npm install expressvarexpress=require('express');//npm install body-parservarbodyParser=require("body-parser");varapp=express();//配置静态文件夹,在本地public读取css,js,html等文件app.use(express.static('public'));//post请求需要body-parser模块处理app.use(bodyParser.urlencoded({extended: false}));app.get('/',function(req,res){res.send('Hello World!');});app.get('/home',function(req,res){//get请求参数对象console.log('get请求参数对象:',req.query);res.send('get请求');});app.post('/home',function(req,res){//post请求参数对象console.log('post请求参数对象:',req.body);res.send('post请求');});varserver=app.listen(3000,function(){varhost=server.address().address;varport=server.address().port;console.log('Example app listening at http://%s:%s',host,port);});匹配路由参数
app.get('/add/:id/:age',function(req,res){//追加请求头res.append("Access-Control-Allow-Origin","*");//?id=xx&age=xxxconsole.log(req.query)//:id/:ageconsole.log(req.params)res.send("Hello Oaoafly");})跨域
可在中间件中追加这句防止跨域
res.append("Access-Control-Allow-Origin","*");模板文件
这个设置视图文件的放置地方,然后配置jade为其模板渲染引擎,这里也需要安装jade模块实现
//views, 放模板文件的目录,比如: app.set('views','./views')//view engine, 模板引擎app.set('view engine','jade')然后安装对应的模板引擎npm包
然后创建一个views文件夹,并在里面新建一个xxxx.jade文件,内容如下
html
head
body
h1 这是测试
p 你好
ul.hhh#dddfor n in news
li=n.title
在中间件中添加如下关键代码,res.render("文件名可省略后缀",{需要渲染在模板上的数据})
app.get('/',function(req,res){connection.query("select * from news",function(err,data){varcontent="Hello Oaoafly";res.render("qianfeng",{//modelname:'xie',name2:'lan',news:data})})//res.send("<p style='color:red'>"+content+"</p>");})静态文件
Express提供了内置的中间件express.static来设置静态文件如:图片, CSS,JavaScript等
你可以使用express.static中间件来设置静态文件路径
例如,如果你将图片, CSS,JavaScript文件放在public目录下
在app.js根目录下创建一个public文件夹,然后在代码中添加
app.use(express.static('public'));设置完静态文件夹后我们可以用res.sendFile(文件路径)方法来把文件发送到前端
注意路径要用绝对路径__dirname + "/public/" + "upload.html"
app.get('/index.html',function(req,res){res.sendFile(__dirname+"/public"+"index.html");})还有值得注意的一点就是,对于每个应用程序,可以有多个静态目录,比如你可以按上传的文件类型分目录,当我们找某张图片的时候就会从这几个静态文件夹中一起找取
app.use(express.static('public'));app.use(express.static('uploads'));app.use(express.static('files'));连接数据库
连接数据库,可以安装mysql模块实现
varmysql=require("mysql");varconnection=mysql.createConnection({host: "localhost",user: "root",password: "",database: "asm"})//执行数据库连接 .close();connection.connect();app.post('/add',function(req,res){//追加请求头res.append("Access-Control-Allow-Origin","*");console.log(req.body);connection.query("insert into news (title,text) values ('"+req.body.title+"','"+req.body.text+"')",function(err,data){console.log(data)})res.send("增加信息");})body-parser
然后通过app.use()方法调用
varexpress=require('express')varbodyParser=require('body-parser')varapp=express()// parse application/x-www-form-urlencoded app.use(bodyParser.urlencoded({extended: false}))// parse application/json app.use(bodyParser.json())cookie-parser
通过app.use()方法调用
varcookieParser=require('cookie-parser')app.use(cookieParser())然后在中间件中通过req.cookies获取前端页面的cookie,是一个通过处理的对象
| module | description |
|---|
| querystring | 将GET请求url中的字符串信息进行转换 |
| chalk | 把控制台输出信息的字符串颜色改变 |
| body-parser | 将客户端通过POST方法传过来的req.body数据解析成json数据 |
| cookie-parser | 处理cookie信息 |
| svg-captcha | 用来生成验证码 |
| trek-captcha | 用来生成验证码 |
| emailjs | 用来通过邮箱找回密码 |
| validator | 验证器 |
| mongodb | 连接mongodb数据库 |
| crypto | express自带的加密模块 |
| express-session | session的认证机制离不开cookie,需要同时使用cookieParser中间件,可以用来保存用户的登陆状态,免密码登陆 |
| formidable | 表单文件上传模块 |
上传文件
node上传文件
热启动
全局安装后,就会有supervisor命令,它会自动检测你的文件变化,一旦变化则会自动重启
过滤器
可以设置对路由的拦截,比如用在登录拦截等
filter.js
exports.authorize=function(req,res,next){if(req.body.token){//res.redirect('/beauty/test');console.log(1)}else{//res.redirect('/beauty/getFemaleList');console.log(2)next();}}路由逻辑
varexpress=require('express');varrouter=express.Router();//模块化varfilter=require('../filter.js');router.get('/getFemaleList',filter.authorize,function(req,res){res.send('hello world');});此时访问/getFemaleList路由的时候就会进入过滤器逻辑,从而实现拦截功能
ES6
要让Express在ES6下跑起来就不得不用转码器Babel了。首先新建一个在某目录下新建一个项目。然后跳转到这个目录下开始下面的操作
全局安装
npm install --save-dev babel-cli -g
然后,可以安装一些presets
cnpm install --save-dev babel-preset-es2015 babel-preset-stage-2
在package.json里添加运行的脚本,这里就可以用ES6代码写程序,babel自动帮我们转ES5运行
"scripts": {"start": "babel-node index.js --presets es2015,stage-2"}可以用babel lib -d dist命令将router文件夹的所有js转码
"scripts": {"start": "babel-node --presets es2015,stage-2","build": "babel router -d dist --presets es2015,stage-2","serve": "node dist/index.js"}脚手架
全局安装
npm install -g express-generator@4
在一个文件夹里面用express命令创建应用架构
进入test文件夹安装依赖,推荐cnpm安装所有依赖
启动应用
SET DEBUG=test:*
npm start
访问在浏览器3000端口号
创建路由
进入到test目录的routes文件夹,然后复制users.js
你可以改变/home这里的路径
var express = require('express');
var router = express.Router();
router.get('/home', function(req, res, next) {
res.send('hello world');
});
module.exports = router;在app.js添加以下两条,该路由就完成了
varhomeRouter=require('./routes/home');//codeapp.use('/test',homeRouter);访问该路径
http://localhost:3000/test/home
配合await和async
letdb=require("../libs/db.js");router.post('/findUser',async(req,res,next)=>{let{
id,
name,
skill
}=req.bodyletdata=awaitdb.connect(`select * from students where ?`,[{
id
}])res.send(data);});Koa
Koa 是一个新的 web 框架,由 Express 幕后的原班人马打造, 致力于成为 web 应用和 API 开发领域中的一个更小、更富有表现力、更健壮的基石。 通过利用 async 函数,Koa 帮你丢弃回调函数,并有力地增强错误处理。 Koa 并没有捆绑任何中间件, 而是提供了一套优雅的方法,帮助您快速而愉快地编写服务端应用程序。——引用Koa的官方文档的原话
所以Koa和Express框架其实很像,个人感觉Koa更轻量
安装
Koa依赖node v7.6.0或ES2015及更高版本和async方法支持
npm i koa
node my-koa-app.js
安装完之后可以新建my-koa-app.js,然后写以下代码,就可以简单创建一个服务器
constKoa=require('koa');constapp=newKoa();app.use(asyncctx=>{ctx.body='Hello World';});app.listen(3000);处理请求和响应
Koa Context将node的request和response对象封装到单个对象中,为编写 Web 应用程序和 API 提供了许多有用的方法,一般将它简写为ctx
ctx.request;// 这是 koa Requestctx.req;// 这是 node Request// 注意:绕过 Koa 的 response 处理是 不被支持的. 应避免使用以下 node 属性:res.statusCode, res.writeHead(), res.write(), res.end()res.statusCoderes.writeHead()res.write()res.end()ctx.requestctx.response;// 这是 koa Responsectx.res;// 这是 node Response
区别于express框架,是在回调函数里面分开写request和response
为方便起见许多上下文的访问器和方法直接委托给它们的ctx.request或ctx.response,不然的话它们是相同的。 例如ctx.type和ctx.length委托给response对象ctx.path和ctx.method委托给request。所以ctx上面综合封装了多个request和response的方法
下面这个负责响应请求体的数据
ctx.response.body=ctx.body=// 简写
将响应体设置为以下之一:
string 写入
Buffer 写入
Stream 管道
Object || Array JSON-字符串化
null 无内容响应
也就是说如果传递数组或者字符串它会自动调用JSON.stringify()来序列化数据,并且response.status如未被设置, Koa将会自动设置状态为200或204。
Context
| GET | POST | JSONP | COOKIE |
|---|
ctx.query | ctx.request.body | ctx.query | ctx.cookies.get(name, [options]) |
注意post请求需要配合koa-bodyparser模块和x-www-form-urlencoded格式,如果是formdata 格式,可以用multer模块来解析
constbodyParser=require('koa-bodyparser');// 需要先安装koa-bodyparser npm install koa-bodyparserapp.use(bodyParser());Request别名
以下访问器和Request别名等效:
ctx.headerctx.headersctx.methodctx.method=ctx.urlctx.url=ctx.originalUrlctx.originctx.hrefctx.pathctx.path=ctx.queryctx.query=ctx.querystringctx.querystring=ctx.hostctx.hostnamectx.freshctx.stalectx.socketctx.protocolctx.securectx.ipctx.ipsctx.subdomainsctx.is()ctx.accepts()ctx.acceptsEncodings()ctx.acceptsCharsets()ctx.acceptsLanguages()ctx.get()
Response别名
以下访问器和Response别名等效:
ctx.bodyctx.body=ctx.statusctx.status=ctx.messagectx.message=ctx.length=ctx.lengthctx.type=ctx.typectx.headerSentctx.redirect()ctx.attachment()ctx.set()ctx.append()ctx.remove()ctx.lastModified=ctx.etag=
Egg
安装
直接使用脚手架,可快速生成项目文件夹
npmiegg-init-gegg-initegg-example--type=simplecdegg-examplenpmi
控制器
第一步需要编写的Controller和Router
// app/controller/home.js(编写文件的位置)constController=require('egg').Controller;classHomeControllerextendsController{asyncindex(){this.ctx.body='Hello world';}}module.exports=HomeController;配置路由映射
// app/router.js(编写文件的位置)module.exports=app=>{const{ router, controller }=app;router.get('/',controller.home.index);};静态资源
Egg 内置了 static 插件,线上环境建议部署到 CDN,无需该插件
static 插件默认映射/public/* -> app/public/*目录
此处,我们把静态资源都放到app/public目录即可
跨域
在config/config.default.js添加以下代码
config.security={csrf: {enable: false,ignoreJSON: true,// 默认为 false,当设置为 true 时,将会放过所有 content-type 为 `application/json` 的请求},domainWhiteList: ['http://localhost:8000'],};config.cors={allowMethods: 'GET,HEAD,PUT,POST,DELETE,PATCH,OPTIONS',};并且在plugin.js添加以下代码
exports.cors={enable: true,package: 'egg-cors',};服务
简单来说,Service 就是在复杂业务场景下用于做业务逻辑封装的一个抽象层,提供这个抽象有以下几个好处:
- 保持 Controller 中的逻辑更加简洁。
- 保持业务逻辑的独立性,抽象出来的 Service 可以被多个 Controller 重复调用。
- 将逻辑和展现分离,更容易编写测试用例,测试用例的编写具体可以查看这里。
所以我们可以把操作数据库的逻辑放在 Service 层
定义 Service 文件
// app/service/user.jsconstService=require('egg').Service;classUserServiceextendsService{// 默认不需要提供构造函数。// constructor(ctx) {// super(ctx); 如果需要在构造函数做一些处理,一定要有这句话,才能保证后面 `this.ctx`的使用。// // 就可以直接通过 this.ctx 获取 ctx 了// // 还可以直接通过 this.app 获取 app 了// }asyncfind(uid){// 假如 我们拿到用户 id 从数据库获取用户详细信息constuser=awaitthis.ctx.db.query('select * from user where uid = ?',uid);// 假定这里还有一些复杂的计算,然后返回需要的信息。constpicture=awaitthis.getPicture(uid);return{name: user.user_name,age: user.age,
picture,};}asyncgetPicture(uid){constresult=awaitthis.ctx.curl(`http://photoserver/uid=${uid}`,{dataType: 'json'});returnresult.data;}}module.exports=UserService;我们就可以在 Controller 层用this.ctx.service.服务名xxx.方法xxx来调用服务里面封装好的方法
// app/router.jsmodule.exports=app=>{app.router.get('/user/:id',app.controller.user.info);};// app/controller/user.jsconstController=require('egg').Controller;classUserControllerextendsController{asyncinfo(){const{ ctx }=this;constuserId=ctx.params.id;constuserInfo=awaitctx.service.user.find(userId);ctx.body=userInfo;}}module.exports=UserController;服务器代理
可以使用curl来代替第三方request模块,或者内置的http.request模块来实现服务器代理通讯
classHomeControllerextendsController{asyncnews(){// 今日头条const{ ctx }=this;const{
data,}=awaitctx.curl('https://m.toutiao.com/list/?tag=video&ac=wap&count=20&format=json_raw&as=A1457C764A41F74&cp=5C6AC19F07943E1&min_behot_time=0&_signature=1Y7F0AAAieymeM-.Mi2uANWOxc&i=',{dataType: 'json',});ctx.body=data;}}
Express
安装
可以参考Express官方文档
首先express环境
编写配置文件index.js,并执行
处理请求
处理GET请求:配合req.query
处理POST请求:需要body-parser模块,配合req.body
req.queryreq.bodyreq.queryreq.cookies匹配路由参数
跨域
可在中间件中追加这句防止跨域
模板文件
这个设置视图文件的放置地方,然后配置jade为其模板渲染引擎,这里也需要安装jade模块实现
然后安装对应的模板引擎npm包
然后创建一个views文件夹,并在里面新建一个xxxx.jade文件,内容如下
在中间件中添加如下关键代码,res.render("文件名可省略后缀",{需要渲染在模板上的数据})
静态文件
Express提供了内置的中间件
express.static来设置静态文件如:图片, CSS,JavaScript等你可以使用
express.static中间件来设置静态文件路径例如,如果你将图片, CSS,JavaScript文件放在
public目录下在
app.js根目录下创建一个public文件夹,然后在代码中添加设置完静态文件夹后我们可以用
res.sendFile(文件路径)方法来把文件发送到前端注意路径要用绝对路径
__dirname + "/public/" + "upload.html"还有值得注意的一点就是,对于每个应用程序,可以有多个静态目录,比如你可以按上传的文件类型分目录,当我们找某张图片的时候就会从这几个静态文件夹中一起找取
连接数据库
连接数据库,可以安装mysql模块实现
body-parser
然后通过
app.use()方法调用cookie-parser
通过
app.use()方法调用然后在中间件中通过
req.cookies获取前端页面的cookie,是一个通过处理的对象cookieParser中间件,可以用来保存用户的登陆状态,免密码登陆上传文件
node上传文件
热启动
全局安装后,就会有
supervisor命令,它会自动检测你的文件变化,一旦变化则会自动重启过滤器
可以设置对路由的拦截,比如用在登录拦截等
filter.js
路由逻辑
此时访问
/getFemaleList路由的时候就会进入过滤器逻辑,从而实现拦截功能ES6
要让Express在ES6下跑起来就不得不用转码器Babel了。首先新建一个在某目录下新建一个项目。然后跳转到这个目录下开始下面的操作
全局安装
然后,可以安装一些presets
在
package.json里添加运行的脚本,这里就可以用ES6代码写程序,babel自动帮我们转ES5运行可以用
babel lib -d dist命令将router文件夹的所有js转码脚手架
全局安装
在一个文件夹里面用
express命令创建应用架构进入test文件夹安装依赖,推荐
cnpm安装所有依赖启动应用
SET DEBUG=test:* npm start访问在浏览器3000端口号
创建路由
进入到test目录的routes文件夹,然后复制
users.js你可以改变
/home这里的路径在
app.js添加以下两条,该路由就完成了访问该路径
http://localhost:3000/test/home配合await和async
Koa
所以Koa和Express框架其实很像,个人感觉Koa更轻量
安装
Koa依赖node v7.6.0或ES2015及更高版本和async方法支持安装完之后可以新建
my-koa-app.js,然后写以下代码,就可以简单创建一个服务器处理请求和响应
Koa Context将node的request和response对象封装到单个对象中,为编写 Web 应用程序和 API 提供了许多有用的方法,一般将它简写为ctx区别于
express框架,是在回调函数里面分开写request和response为方便起见许多上下文的访问器和方法直接委托给它们的
ctx.request或ctx.response,不然的话它们是相同的。 例如ctx.type和ctx.length委托给response对象ctx.path和ctx.method委托给request。所以ctx上面综合封装了多个request和response的方法下面这个负责响应请求体的数据
将响应体设置为以下之一:
也就是说如果传递数组或者字符串它会自动调用
JSON.stringify()来序列化数据,并且response.status如未被设置,Koa将会自动设置状态为200或204。Context
ctx.queryctx.request.bodyctx.queryctx.cookies.get(name, [options])注意
post请求需要配合koa-bodyparser模块和x-www-form-urlencoded格式,如果是formdata格式,可以用multer模块来解析Request别名以下访问器和
Request别名等效:Response别名以下访问器和
Response别名等效:Egg
安装
直接使用脚手架,可快速生成项目文件夹
控制器
第一步需要编写的
Controller和Router配置路由映射
静态资源
Egg 内置了 static 插件,线上环境建议部署到 CDN,无需该插件
static 插件默认映射
/public/* -> app/public/*目录此处,我们把静态资源都放到
app/public目录即可跨域
在
config/config.default.js添加以下代码并且在
plugin.js添加以下代码服务
简单来说,Service 就是在复杂业务场景下用于做业务逻辑封装的一个抽象层,提供这个抽象有以下几个好处:
所以我们可以把操作数据库的逻辑放在 Service 层
定义 Service 文件
我们就可以在 Controller 层用
this.ctx.service.服务名xxx.方法xxx来调用服务里面封装好的方法服务器代理
可以使用
curl来代替第三方request模块,或者内置的http.request模块来实现服务器代理通讯