express学习-express搭建后台
前言:本文是纯用node express做一个后端服务的教程,并不等同于express官网的入门教程,本文也并不涉及任何高级的Node服务端性能优化等知识。
本文是在已经看过express官方入门指南,和用express做过一点项目经验后,再次重新学习express的一篇私人笔记。所以一些基础知识,本文将会一笔带过
已经看过express官网的小仙女小哥哥们可能会发现,按照官网教程(不管是否使用generator),撘起来的一个应用,是同时包含前端逻辑和后端逻辑的,比如可以用.get(/)这种方式,既可以.render(),.sendfile()等方法输出一个html页面在网页上,也可以.json()等方式返回一个json对象(如同一般的前后端项目时,前端同学请求后端java接口,后端返回给前端的数据一样)。
但在vue和webpack流行的当下,很多前端项目是用的webpack提供的编译服务环境在跑的,最后打包压缩成一个html一个js,发给后端同学去部署,这样子,再结合express用的的时候,就没有必要再在express里设置什么view engine(前端模板引擎jade,ejs等)、也不用配置什么less/sass编译(因为webpack的loader会做的)。
所以本文的意思,就是只用express做一个后端服务:接受并返回前端的get\post\put\delete等请求内容。就是一个纯的服务端。顺便重新学习一下各个express中间件。
目录
--------------------------------------------分割线-------------------------------------------------------
一、搭建一个最简单的express后端服务,仅接受和返回get请求
*基础环境:安装好你的node和express。node8.9.X以上,express4(3和4有很大不同)
*express官网: http://www.expressjs.com.cn/4x/api.html#res
*我的电脑系统:mac (部分步骤如果在windows上有不同或者报错,等我以后如果用windows做开发了再说)
**步骤**
1.新建项目文件夹,里面新建一个app.js和package.json。结构如下:
node_modules是待会用‘npm install’下载下来的 。
--app.js--
1 /** 2 * Module dependencies. 3 */ 4 5 var express = require('express'); 6 var http = require('http'); 7 8 9 var app = express(); 10 11 // all environments 12 app.set('port', 3000); 13 14 15 http.createServer(app).listen(app.get('port'), function(){ 16 console.log('Express server listening on port ' + app.get('port')); 17 });
--package.json--
{ "name": "basicBackend", "version": "1.0.0", "private": true, "scripts": { "start": "node app" }, "dependencies": { "express": "~4.14.1" }, "devDependencies": {} }
建好这2个文件后,npm install 一下下载node_modules,一个最简单的服务端只需要express和http这2个模块。
然后打开终端/命令行,cd到本文件夹底下 npm run start 把项目运行起来。
出现图中文字,表示服务启动成功。
2.新建一个get请求。
预期效果是:html页面里用jquery的$.ajax去请求该get接口,能正常被响应和获得返回值,如同一般的前端请求java后端接口。
修改app.js如下(黄色表示新增):
1 /** 2 * Module dependencies. 3 */ 4 5 var express = require('express'); 6 var http = require('http'); 7 var bodyParser = require('body-parser'); 8 9 var app = express(); 10 app.set('port', 3000); 11 12 app.get('/getUserInfo', function(req, res, next){ 13 console.log('get用户请求数据为:'); 14 console.log(req.query); 15 16 res.json({ 17 meta:{ 18 code:200 19 }, 20 data:{ 21 message:'蛤蟆皮' 22 } 23 }); 24 }); 25 26 http.createServer(app).listen(app.get('port'), function(){ 27 console.log('Express server listening on port ' + app.get('port')); 28 });
---解释---:
(1)、app.get()表示接收所有前端来的get请求方式,同理,app.post(),app.delete()分别表示接受前端发来的post请求与delete请求方式。
(2)、app.get(path, callback [, callback ...]):传参,第一个参数是路径,后面的参数都是是回调函数,可以放1个或者多个回调函数,一般只用到1个回调,本例也只用了1个回调。官方对这个方法的解释是:Routes HTTP GET requests to the specified path with the specified callback functions,意即‘用指定回调方法向指定路径发送http get请求’,通俗讲就是对path参数表示的接口执行一些操作,这些操作写在第二个参数即回调函数内。
(3) app.get()中的第二个(+)参数---回调函数:该回调函数接受3个参数,按照大多数人的不成文的书写惯例,这三个传参写作req, res, next。第一个参数表示http请求对象(request),第二个参数表示response对象,第三个参数是next函数,表示将控制权交给下一个中间件。next有点复杂不详说,只要记住一个请求结束后,不要后面写next(),常见的res.send(),res.json()都属于请求结束,后面不要再写next()了.
(4)res.json(obj) 表示返回一个json对象,该对象的详细数据就是括号里的东西啦。
----------
保存并重启项目。
3.然后另建一个前端项目,里面新建个html,写个ajax请求试一下这个接口:(这个html就不要放在本express项目内了,以免引起混淆,而且下面我要说解决跨域,如果该html文件建在本express项目内就不会出现跨域问题了)。
testRequestMyExpressBack.html
$.ajax({
url:'http://192.168.0.105:3000/getUserInfo',
type:'get',
data:{
id:233,
name:'小明'
},
success:function(p){
console.log(p);
console.log(p.data);
},
error: function(x,h,r){
console.log(r)
}
});
不出所料的话,这个html会报错跨域。所以此处使用‘停用跨域策略的google浏览器或则safari浏览器’。然后浏览器控制台里可以看到本次请求的结果:
express服务端返回的数据,也正如例中所写。至此一个能正常响应前端发来的get请求的express服务端就算完成了。下文开始,继续配置其他参数和模块使其能响应POST/PUT/DELETE请求、允许跨域、打印台输出日志等常见功能。
二、让express服务端允许跨域
app.js里加上这2句:
var express = require('express'); var http = require('http'); var app = express(); app.set('port', 3000); app.all('*', function(req, res, next) { res.header("Access-Control-Allow-Origin", "*"); res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,PATCH,OPTIONS"); next(); }); app.get('/getUserInfo', function(req, res, next){ .........
--解释--:
(1)Access-Control-Allow-Origin", "*" 表示允许来自所有源的。
(2)Access-Control-Allow-Methods","PUT,POST,GET,DELETE,PATCH,OPTIONS" 表示允许跨域的请求方式。
(3)res.header(): .header()是response对象的一个方法,用于给response头设置键值。它是res.set()的别名,传参一毛一样
这一段要放在最上头。
三、新增一个post接口示例:
post接口的写法与get相似,但是整个app.js中需要额外引入body-paser这个中间件来解析前端传入的数据。
var express = require('express'); var http = require('http'); var bodyParser = require('body-parser');//引入body-parser var app = express(); // all environments app.set('port', 10303); app.use(bodyParser.json());//使用bodyparser并配置其参数 app.use(bodyParser.urlencoded({ extended: false }));//使用bodyparser并配置其参数
body-parser 官网https://www.npmjs.com/package/body-parser
官方说明为Parse incoming request bodies in a middleware before your handlers, available under the req.body
property.
意即:在执行你自己的事件前,先解析传入的请求体(request bodies),你可以直接使用req.body来得到解析后的请求体。例如:
前端js中:
//这是一个很常见的前端ajax post请求
$.ajax({ url:'http://192.168.0.105:10303/postUserInfo', type:'post', data:{ age: 85 }, success:function(p){ $("#result").html(p); console.log(p); }, error: function(x,h,r){ console.log(r) } });
现在在express项目中的app.js中新写一个post接口:
app.post('/postUserInfo', function(req, res, next){ console.log('post用户请求数据为:'); console.log(req.body);//打印结果为{age: 85},也就是前端ajax中的data字段的值 res.json({ meta:{ code:200 }, data:{ message:'啦啦啦啦啦' } }); });
四、新增put\pathc\delete接口示例:
写法与post和get的一致。例如:
app.put('/putUserInfo', function(req, res, next){ console.log('put用户传入数据为:'); console.log(req.body); res.json({ meta:{ code:200 }, data:{ message:'请求putUserInfo接口成功' } }); }); app.delete('/deleteUserInfo', function(req,res,next){ console.log(req.body); res.json({ meta:{ code:200, message:"success_我的deleteUserInfo接口成功" }, data:null }); });
但是需要注意跨域的问题,(如果整个项目不存在跨域,可以pass本小节)。
只以跨域中的Preflighted Request(预检请求)为例:
修改app.js中关于跨域一段的设置:
app.js
app.all('*', function(req, res, next) { res.header("Access-Control-Allow-Origin", "*"); res.header("Access-Control-Allow-Methods","OPTIONS,PUT,POST,GET,DELETE,PATCH"); if(req.method === 'OPTIONS'){ res.statusCode = 200; res.end(); }else{ next(); } });
l另外推荐一个第三方跨域处理的包CORS:https://github.com/expressjs/cors。可处理多种自定义配置。
五、总结
至此一个基础的可以跨域的响应前端发送来的get/post/put/delete等请求的最简express程序就完成了。项目地址:https://github.com/hamuPP/express-study/tree/master/basicBackend
当然,一个完整的express后端至少还需要设置cookie,session,还有常见用法.use()也并未涉及