Node.js+Express+Vue.js项目开发实战(txt+pdf+epub+mobi电子书下载)

作者:张旭

出版社:机械工业出版社

格式: AZW3, DOCX, EPUB, MOBI, PDF, TXT

Node.js+Express+Vue.js项目开发实战

Node.js+Express+Vue.js项目开发实战试读:

前言

一直以来,用于后端开发的主流语言是Java、PHP和Python等;而Node.js的出现让JavaScript的身影出现在了后端开发中,这使得前后端使用同一种语言并统一模型的梦想得以实现。

Node.js不是一种独立的语言,而是一个基于Chrome V8引擎的JavaScript运行环境,其底层语言仍是JavaScript。Node.js可以方便地搭建响应速度快、易于扩展的网络应用。它使用事件驱动、非阻塞I/O模型而得以轻量和高效,非常适合在分布式设备上运行数据密集型的实时应用。使用Node.js可以让用户花最低的硬件成本,追求更高的并发效率和处理性能。具体而言,Node.js具有以下几个特性:

·事件驱动:JavaScript是一种事件驱动编程语言,事件发生时调用的回调函数可以在捕获事件处进行编写,这样可以让代码容易编写和维护。

·非阻塞:在非阻塞模式下,一个线程永远在执行计算操作,这个线程所使用的CPU核心利用率永远是100%,使得效率大大提高,节省资源。

·异步I/O:也称非阻塞式I/O,针对所有的I/O操作均不采用阻塞策略。当线程遇到I/O操作时,不会以阻塞方式等待I/O操作的完成或数据的返回,而只是将I/O请求发送给操作系统,继续执行下一条语句。当操作系统完成I/O操作时,以事件的形式通知执行I/O操作的线程,线程会在特定时间处理这个事件。

·高并发能力:Node.js并不会为每个客户的连接创建一个新的线程,而仅仅使用一个线程。当有用户连接时,就触发一个内部事件,通过非阻塞I/O和事件驱动机制,让Node.js程序宏观上也是并行的。

·社区活跃:Node.js的社区在不断地壮大,其包的数量在快速增加,质量也在不断提升。最主要的是很多包都简单灵巧,方便用户使用和快速开发。本书编写目的

实践对于学习知识的重要性不言而喻。只有理论知识而没有实践不可能真正完成一个项目的开发。基于此笔者编写了本书。

本书专为Node.js项目经验薄弱的初学者、进阶者和爱好者打造,旨在让他们掌握Node.js的相关知识和技能,并能进行项目实战开发。本书从实际项目开发入手,详细讲解了3个项目案例的完整开发过程,让读者可以快速巩固所学的理论知识,并能结合理论知识完成实际的商业项目。

当您认真、系统地学习完本书内容之后,将会发现自己已经成为一名真正的Node.js程序员,已经能够实打实地开发实际项目了。本书特色

·快速上手:本书采用Node.js中最流行的框架Express进行项目开发,让读者能够快速熟悉并使用Express框架。

·技术新颖:本书不仅讲解了传统的后端渲染架构,还提供了业内新近流行的前后端分离架构,让读者能够深入了解架构知识,跟上技术发展的步伐。

·注重实战:本书采用实际的商业项目作为案例,逐一讲解项目开发中的需求分析、架构设计和代码编写等知识,让读者能够在实战中掌握知识,提升项目经验。

·新颖独特:本书在项目开发中提供了一种基于Express框架搭建的文件目录结构,读者可以根据此结构快速、高效地开发出新的商业项目。本书内容

本书共6章,从实战角度出发,以项目开发流程为指引,一步步指导读者学习如何开发完整的项目。

第1章介绍了Node.js最流行的Web开发框架Express,讲述了Express的主要特性和使用方法,以及如何使用Express创建一个项目。

第2章从需求分析、系统设计、数据库设计及代码编写几个方面,详细介绍了许愿墙项目的前台展示系统的开发。

第3章在第2章的基础上详细介绍了许愿墙项目的后台管理系统的开发。该系统用来对项目的信息进行查看和管理,采用了当下比较流行的前后端分离架构。

第4章详细介绍了博客管理系统的开发。该系统包括前台展示系统和后台管理系统两部分,其功能相互独立。

第5章详细介绍了装修小程序管理系统的开发。该系统包括前台展示系统和后台管理系统这两个功能相互独立的系统,其中重点介绍了前后端开发架构下的后端API接口开发和前端页面开发。

第6章介绍了Node.js部署的相关知识,包括如何安装Node.js环境、如何提取项目代码,以及如何使用Node.js进程管理工具PM2等。读者对象

·对Node.js感兴趣的各类开发人员;

·有一定Node.js基础但没有项目经验的初学者与进阶者;

·有一定Node.js基础,想要实际开发项目的开发人员;

·高校及培训机构的老师和学生;

·正在进行毕业设计的学生。配套资源获取

本书涉及的所有源代码文件等配套资源需要读者自行下载,请到华章公司的网站(www.hzbook.com)搜索本书,即可在本书页面上找到相关下载链接。

另外,笔者还将配套资源上传到了QQ群共享文件中(群号:620379726),您也可加入QQ群获取资源。但需要注意,如果加入QQ群时系统提示此群已满,请根据验证信息加入新群。Node.js学习资源

·JavaScript教程:http://www.w3school.com.cn/js/index.asp;

·Node.js官网:https://nodejs.org;

·Node.js官方文档:https://nodejs.org/en/docs/;

·Express官网:http://expressjs.com;

·Node.js中文社区:https://cnodejs.org。本书作者

本书由张旭编写。在写作过程中,笔者竭尽所能将本书写好,力图为读者呈现一本易学、实用的图书,但因水平所限,仍难免有疏漏和不妥之处,敬请广大读者指正。您在阅读本书时若有疑问或任何建议,都可以通过以下方式联系我们。

E-mail:jiuri2000@126.com或hzbook2017@163.com(编辑部);

QQ交流群:620379726。第1章 安装和使用Express

Express是一个精简、灵活的Node.js的Web应用程序开发框架,为Web和移动应用程序提供了一组强大的功能。它是Node.js中最流行的Web开发框架,被大多数开发人员所使用。使用Express可以快速地开发一个Web应用,其他的开发框架也都是基于Express构建的。1.1 安装Express

要安装Express,首先要具备Node.js环境,也就是说你已经安装了Node.js。

安装Express非常简单,使用Node.js的配套工具npm命令即可安装:$ npm install -g express-generator

npm命令运行完毕,再运行命令:$ express --version

如果能够看到Express的版本号,证明Express已经安装成功。截至本书写完,Express最新的版本号是4.16.0。$ express --version$ 4.16.0

其实这里安装的是一个应用生成器工具——express-generator,通过它可以快速创建一个应用的骨架,为快速创建Node.js项目提供便利。1.2 使用Express创建项目

在安装完Express之后,就可以使用Express命令来创建一个新的项目了。1.2.1 创建项目

使用Express创建项目非常简单,具体步骤如下:(1)按WIN+R键打开“运行”对话框,输入cmd命令,单击“确定”按钮打开命令行窗口,如图1-1所示。图1-1 命令行窗口(2)进入工作目录,可以自定义一个工作目录,如下:$ e:$ cd express/code(3)执行创建命令,创建一个名为hello的Express项目:$ express hello(4)此时可以看到它会自动执行,图1-2代表创建成功。图1-2 Express创建hello项目(5)创建成功之后会在code目录下出现一个名叫hello的目录,进入hello目录,然后安装依赖包:$ cd hello$ npm install(6)安装完毕之后,执行命令启动应用:$ npm start(7)应用启动后,在浏览器中输入http://localhost:3000/网址就可以看到名叫hello的这个应用了,如图1-3所示。图1-3 Express默认应用启动界面1.2.2 Express项目结构分析

项目正常启动后,我们用开发工具打开hello项目看一下它的目录结构,如图1-4所示。图1-4 Express默认应用的目录结构

项目结构不太复杂是不是?相比较其他语言的框架来说很轻量,这也是Node.js快速开发的一个特色。

目录结构中的文件及其作用如表1-1所示。表1-1 Express默认应用中的文件及其作用1.2.3 应用主文件app.js

app.js文件相当于项目启动的主入口文件,有一些公共方法和服务器配置等信息。代码分析如下:var createError = require('http-errors'); // http错误处理模块var express = require('express'); // 引入Expressvar path = require('path'); // 引入pathvar cookieParser = require('cookie-parser'); // 引入cookie处理对象var logger = require('morgan'); // 引入日志模块var indexRouter = require('./routes/index'); // 引入路由目录中的index.js文件var usersRouter = require('./routes/users'); // 引入路由目录中的users.js文件var app = express(); // 创建Express应用app.set('views', path.join(__dirname, 'views')); // 定义页面目录app.set('view engine', 'jade'); // 定义页面模板引擎app.use(logger('dev')); // 定义日志打印级别app.use(express.json()); // 定义JSON格式处理数据// 定义使用urlencode处理数据及querystring模块解析数据app.use(express.urlencoded({ extended: false }));app.use(cookieParser()); // 定义使用cookie处理对象// 定义静态资源目录publicapp.use(express.static(path.join(__dirname, 'public')));app.use('/', indexRouter); // 定义指向index.js的路由app.use('/users', usersRouter); // 定义指向users.js的路由// 定义404错误处理app.use(function(req, res, next) { next(createError(404));});// 定义其他错误处理app.use(function(err, req, res, next) { // 设置locals,只在开发环境生效 res.locals.message = err.message; res.locals.error = req.app.get('env') === 'development' ? err : {}; res.status(err.status || 500); // 返回错误http状态码 res.render('error'); // 渲染错误页面});module.exports = app;1.3 Express路由

接触到一款框架,首先要熟悉的就是它的路由。路由是指应用程序的端点(URI)如何响应客户端请求。通俗来说,就是定义什么路径来访问。1.3.1 GET请求路由

在Express中定义路由特别简单。首先来看一下routes目录中的index.js路由文件,也就是首页路由文件,它是一个GET请求路由,如下:var express = require('express'); // 引入Expressvar router = express.Router(); // 引入Express路由对象//首页路由router.get('/', function(req, res, next) { res.render('index', { title: 'Express' });});module.exports = router; // 导出路由

首页路由文件很简单,其中也只定义了一个根目录的路由。

将其中的代码:res.render('index', { title: 'Express' });

更换成如下代码:res.render('index', { title: Hello});

保存文件,重新运行npm start命令,用浏览器打开http://localhost:3000查看效果,因为在浏览器地址栏中输入地址发送的请求默认是GET请求,所以可以得到如图1-5所示的结果。

可以看到,之前的Express被换成了Hello。

前面的一段代码定义了首页的路由,这个路由定义的是GET请求,请求的是“/”路径,也就是根路径。接着后面跟着一个方法,当用户发送GET请求根路径的时候,就进入这个方法中,在这个方法中可以进行一些对请求的操作。图1-5 将Express更改成Hello的运行效果

Express默认的首页方法中使用了res.render()方法,该方法的作用是渲染页面。其第一个参数就是页面的文件名,这里对应的就是views目录中的index.jade文件;第二个参数是传入到页面文件的对象,可以将数据渲染到页面上。1.3.2 自定义路由

分析过首页路由之后,可以试着自己写一个路由。在index.js路由文件中添加如下代码:// 定义一个GET请求“/world”的路由,执行方法router.get('/world', function(req, res, next) { res.render('index', { title: 'Hello World' }); // 渲染index页面});

将项目重新启动,打开浏览器请求地址http://localhost:3000/world,会看到新的页面,如图1-6所示。图1-6 Hello World路由演示效果

新定义的路由生效了,是不是很简单呢?

但是每次更改过路由文件都要重新启动项目才会生效,如此,开发效率不太高。在这里,给大家推荐一个工具——nodemon,其安装方式也是利用npm命令:npm install -g nodemon

安装完成之后,修改项目根目录中的package.json文件,将其中的"scripts": { "start": "node ./bin/www"},

修改成:"scripts": { "start": "nodemon ./bin/www" // 使用nodemon运行},

然后再执行npm start命令启动项目,这样在路由文件被更改并保存之后,会自动重启项目,并可以立刻在浏览器中看到更改后的运行结果。1.3.3 其他请求方式的路由

HTTP请求方式除了GET之外,还有POST、PUT等其他方式。类似于GET请求的路由编写方式,其他请求方式也换成相应的router方法,如下:// POST请求方式router.post('/world', function(req, res, next) { res.render('index', { title: 'Hello World' }); // 渲染index页面});// PUT请求方式router.put('/world', function(req, res, next) { res.render('index', { title: 'Hello World' }); // 渲染index页面});// DELETE请求方式router.delete('/world', function(req, res, next) { res.render('index', { title: 'Hello World' }); // 渲染index页面});

大家可以自己尝试一下相应的请求方式。1.3.4 路由匹配规则

前面演示的路由匹配都是完整匹配,即定义“/world”,在浏览器中要输入“/world”才能匹配到。

在Express中,除了完整匹配,还支持模糊匹配,例如:router.get('/wes?t', function(req, res, next) { res.render('index', { title: 'Hello World' });});

在浏览器中查看,会发现当请求http://localhost:3000/west和http://localhost:3000/wet时都可以成功。

同样,模糊匹配还可以按如下处理:// 能够匹配/west、/weest、/weeest等router.get('/we+st', function (req, res, next) { res.render('index', { title: 'Hello World' });})// 能够匹配/west、/wtrouter.get('/w(es)?t', function (req, res, next) { res.render('index', { title: 'Hello World' });})// 能够匹配/west、/we123st、/wexxxst等router.get('/we*st', function (req, res, next) { res.render('index', { title: 'Hello World' });})// 能够匹配/west、/we123st、/wexxxst等router.get('/we*st', function (req, res, next) { res.render('index', { title: 'Hello World' });})

同时,Express路由还支持正则表达式,如下:// 能够匹配路径中包含west的任何内容,如/west、/aawest、/westee等router.get(/west/, function (req, res, next) { res.render('index', { title: 'Hello World' });})1.3.5 中间件

在项目开发过程中,有时会需要用共同的方法来拦截请求,比如需要对请求做一些身份验证。

如果接口是一个或两个的话,可以在某个接口的处理方法中进行验证,但是如果很多接口都需要进行验证的话,就不可能在每一个需要验证的接口上都添加一套代码,那样既费时又费力。为了提高效率,需要将验证的方法单独提出来。

Express提供了一个很好的工具,即中间件。可以在中间件中定义一个验证方法,然后在需要验证的接口路由上添加验证中间件,完成接口的验证。

那么什么是中间件呢?这里的中间件是一些处理方法的合集。Express其实就是一个路由和中间件合成的Web框架。

在前面说过,当前端请求路由的时候,会进入后面的路由处理方法中打开前面的index.js路由文件,查看根路径的路由:router.get('/', function(req, res, next) { res.render('index', { title: 'Express' });});

当前端使用GET方法请求根路径的时候,会进入第二个参数function中,而这个路由处理方法就是Express中的中间件。

Express的中间件函数可以让我们访问请求对象Request、响应对象Response及下一个中间件函数。其中,下一个中间件函数通常声明为next。

在Express中,中间件会被Express传入3个参数,如表1-2所示。表1-2 Express中间件的3个参数

为了实现上述验证功能,可以在路由处理方法之前也就是中间件之前再加一个方法,例如:// 定义一个GET请求router.get('/car', function(req, res, next){ console.log ('这里是中间件'); // 打印日志,方便查看 next(); // 继续下一步,下一个中间件}, function(req, res, next) { res.send('这里是返回'); // 向页面发送数据});

在router.get()方法中,在前面定义的路由处理方法之前又传入了一个方法,这时使用浏览器访问http://localhost:3000/car,会看到控制台中打印出“这里是中间件”,同时浏览器的页面上展示出“这里是返回”。

在中间件中可以做很多事情,在后面的实战项目演示中大家将会经常见到它。1.4 Express页面

在前面定义路由的时候,用到的处理方法中有这么一行代码:res.render('index', { title: 'Hello World' });

这行代码是Express的返回对象Response的一个render()方法,这个后面会讲。这里先来讲render()方法的第一个参数,也就是需要渲染的模板文件名,也就是对应views目录中的文件,即页面文件。

在前面分析项目结构的时候已经说过,页面目录中有3个页面文件:index.jade、error.jade和layout.jade。大家可能对jade这样的拓展名文件不太熟悉,其实它就是一种模板引擎,为了使用大家熟悉的HTML结构,通常在项目实际开发过程中会将其更换成便于理解的其他模板引擎,比如art-template等。1.4.1 更换模板引擎

Express默认的模板引擎是jade,为了便于新用户上手开发,需要把它替换成更简洁、高效的art-template。

更换模板引擎的方法也很简单,首先需要安装art-template依赖包,分别执行以下命令:npm install -S art-templatenpm install -S express-art-template

两个依赖包都安装成功之后,修改项目根目录下的app.js文件,将其中的app.set('view engine', 'jade');

更换成app.engine('.html', require('express-art-template'));app.set('view engine', 'html');

接着到views目录下新建一个index.html文件,如下:
Title

这是一个HTML文件

然后去浏览器中预览一下效果。如图1-7所示,模板引擎已经更换成功。图1-7 更改模板引擎为art-template1.4.2 渲染数据到页面上

在开发网页的时候,网页上的内容往往都不是一成不变的,而是根据服务端内容变化的,这就需要将数据渲染到页面上。

在前面的章节中说过,在Express中将数据渲染到页面上的方法是response对象的render()方法的第二个参数,如下:// 定义一个GET请求“/”的路由router.get('/', function(req, res, next) { res.render('index', { title: 'Hello' });// 渲染index页面,并传送变量title});

这段代码在渲染的时候向index.html页面中传入了一个值为Hello的title字段,但是在浏览器中预览却没有看到这个Hello,这是因为还没有编辑页面文件来接收这个title字段。

打开views目录中的index.html文件,在其中的标签中添加以下代码:

这是title的值:{{title}}

在浏览器中预览,效果如图1-8所示。图1-8 页面接收参数的值

还可以多定义一些参数,让页面来接收,如下:router.get('/', function(req, res, next) { // 定义一个GET请求“/”的路由 res.render('index', { // 渲染index页面,传入对象 title: 'Hello', name: '零度逍遥', age: 31 });});

修改对应的页面文件index.html:
Title

{{title}}

大家好,我是{{name}},我今年{{age}}岁,很高兴认识大家!

浏览器的效果如图1-9所示。图1-9 页面接收多个参数的值

怎么样?是不是很简单呢?只需要在需要渲染的地方将后端输出的字段用{{}}双花括号括起来就行了,赶快自己试一下吧。1.4.3 条件渲染

现在已经能够做到将数据渲染到页面上了。但是有时会有这样的需求:根据不同的情况展示不同的页面,这个时候就需要用条件渲染了。1.基本条件渲染

还是基于上一节中的示例,现在需要实现:如果我的年龄大于等于30岁,就不展示“我今年XX岁”这些文字,如果小于30岁,则展示文字。

将index.js的路由代码修改为:router.get('/', function(req, res, next) { // 定义一个GET请求“/”的路由 // 渲染index页面,传入渲染对象 res.render('index', { title: 'Hello', name: '零度逍遥', age: 25 });});

将对应的index.html页面文件修改为:
Title

{{title}}

{{if age<30 }}

大家好,我是{{name}},我今年{{age}}岁,很高兴认识大家!

{{/if}}{{if age>=30 }}

大家好,我是{{name}},很高兴认识大家!

{{/if}}

在浏览器里得到的页面如图1-10所示。图1-10 条件渲染显示年龄

现在还是显示年龄的,将路由代码修改为:// 定义一个GET请求“/”的路由router.get('/', function(req, res, next) { // 渲染index页面,传入渲染对象 res.render('index', { title: 'Hello', name: '零度逍遥', age: 32 });});

现在再次预览页面,效果如图1-11所示。图1-11 条件渲染隐藏年龄

这时就不会显示年龄了,因为页面文件中的那段条件渲染代码生效了。在art-template中,如上述示例,if判断有固定的写法,用{{if CONDITION}}开头,以{{/if}}结尾,将需要判断的代码放在其中。2.嵌套条件渲染

除了基本的条件渲染外,很多时候往往存在复杂的情形,需要进行多层判断。art-template也提供了嵌套条件渲染的方式,在条件判断里继续增加条件判断,即嵌套if判断,将页面文件代码更改如下:
Title

{{title}}

{{if age<30 }}

大家好,我是{{name}},我今年{{age}}岁,很高兴认识大家!

{{/if}}{{if age>=30 }}

大家好,我是{{name}}, {{if happy }} 很高兴认识大家! {{/if}}

{{/if}}

修改路由代码:// 定义一个GET请求“/”的路由router.get('/', function(req, res, next) { // 渲染index页面,传入渲染对象 res.render('index', { title: 'Hello', name: '零度逍遥', age: 42, happy: false });});

这样页面又发生了变化,如图1-12所示。图1-12 嵌套条件渲染显示

将happy的值设为true:// 定义一个GET请求“/”的路由router.get('/', function(req, res, next) { // 渲染index页面,传入渲染对象 res.render('index', { title: 'Hello', name: '零度逍遥', age: 42, happy: true });});

页面又发生了变化,如图1-13所示。图1-13 嵌套条件渲染隐藏

是不是很方便呢?不仅如此,art-template模板引擎可以在页面上的任意地方使用条件渲染,快点去试试吧。1.4.4 循环渲染

在页面开发过程中,除了条件渲染,循环渲染也是一种常用的方式,最常见的就是渲染一个列表。在art-template中,循环渲染也特别简单。1.基本循环渲染

首先在路由中定义一个数组,数组中的每一项都是一个对象,需要将数组渲染到页面上,每一条数据对应数组中的一项。

定义路由的代码如下:// 定义一个GET请求“/”的路由router.get('/', function(req, res, next) { // 渲染index页面,传入渲染对象 res.render('index', { title: 'Hello', // 定义一个数组,每一项都是一个对象 list: [{ id: 1, content: '今天天气不错' }, { id: 2, content: '昨天你吃了什么?' }, { id: 3, content: '工作好累' }] });});

修改页面文件代码:
Title

{{title}}

{{each list as item }}

数据id:{{item.id}},内容:{{item.content}}

{{/each}}

在浏览器中查看,如图1-14所示。图1-14 循环渲染

特别简单是不是?跟条件渲染一样,在art-template中循环渲染也有固定的写法:以{{each LIST as ITEM}}(LIST为数组字段,ITEM为数组中的每一项)开头,以{{/each}}结尾,需要循环的内容放在其中。2.循环渲染结合条件渲染

在实际的业务场景中,通常不会简单地渲染列表,而往往需要在循环过程中进行一些判断,根据判断的结果展示不同的页面,也就是在循环渲染中增加条件渲染。

下面结合上一节的条件渲染给大家展示一个综合的例子。定义路由代码:// 定义一个GET请求“/”的路由router.get('/', function(req, res, next) { // 渲染index页面,传入渲染对象 res.render('index', { title: 'Hello', // 定义一个数组,每一项都是一个对象 list: [{ id: 1, content: '今天天气不错' }, { id: 2, content: '昨天你吃了什么?' }, { id: 3, content: '工作好累' }], targetId: 2 // 定义一个变量,表示当前被选中的id });});

修改页面文件代码:
Title

{{title}}

{{each list as item }}{{if item.id === targetId}}

数据id:{{item.id}},内容:{{item.content}}

{{else}}

数据id:{{item.id}},内容:{{item.content}}

{{/if}}{{/each}}

浏览器预览效果如图1-15所示。

在这个示例中,对list这个数组字段进行了循环渲染,同时在循环中又进行了判断,只有当list中某一条数据的id值等于targetId这个字段值的时候,才将这一条数据展示为红色。图1-15 循环渲染配合条件渲染1.5 请求对象Request

前面说过,当请求到路由的时候会进入路由处理方法中,而路由处理方法本质上就是一个中间件,它包括3个参数,即请求对象Request、返回对象Response和下一步方法next。下面介绍一下请求对象Request的常用属性。1.5.1 Request.url属性:获取请求地址

Request.url属性是获取请求地址的属性。看看示例,添加一个/abcd的路由:// 定义一个GET请求“/abcd”的路由router.get('/abcd', function(req, res, next) { console.log (req.url); // 打印Request.url属性值 res.render('index', { title: 'Express' });});

在浏览器中请求http://localhost:3000/abcd时,控制台就会打印“/abcd”,对应的就是请求地址。还可以定义一个多层级的路由:router.get('/abcd/efg', function(req, res, next) { console.log (req.url); res.render('index', { title: 'Express' });});

这个时候,控制台就会打印“/abcd/efg”,依旧是对应请求地址。

在url后面加入一些参数看看:router.get('/abcd/efg?name=jim&age=25', function(req, res, next) { console.log (req.url); res.render('index', { title: 'Express' });});

控制台打印的结果是“/abcd/efg?name=jim&age=25”。

另外,在请求的时候还可以这样传入参数:router.get('/book/:id', function(req, res, next) { console.log (req.url); res.render('index', { title: 'Express' });});

这里的“:id”代表着请求的时候,这里可以传入一个id字段,即http://localhost:3000/book/2,这时控制台打印的结果是“/book/2”1.5.2 Request.query属性:获取GET请求参数

Request.query属性常用来获取GET请求参数,它是一个对象,包含路由中每个查询字符串参数的属性。如果没有查询字符串,则为空对象{}。

在路由的url中添加一个参数id=15:// 定义一个GET请求“/book”的路由router.get('/book', function(req, res, next) { console.log (req.query); // 打印GET请求参数 res.render('index', { title: 'Express' });});

在浏览器中打开http://localhost:3000/book?id=15,控制台打印结果为“{id:15}”。注意:不能在路由中将请求地址定义成“/book?id=15”,因为这样它会解析成其他的字符串,而给不出你想要的结果。

再向路由中添加两个参数:author=jim=time=2015-05-04。

在浏览器中打开http://localhost:3000/book?id=15&author=jim&time=2015-05-04,控制台打印的结果为“{id:'15',author:'jim',time:'2015-05-04'}”。注意:Request.query只能获得GET请求方式,或者拼接在url后面的参数,不能获取其他请求方式(POST、PUT等)的参数。1.5.3 Request.body属性:获取POST请求参数

介绍完获取GET请求方式的参数之后,再来介绍另外一个常用的请求方式POST参数的获取方法。

和获取GET参数方式一样简单,Express已经将POST请求参数封装在了Request.body对象中,它同样是以键值对的形式存在,方便得到处理。

定义一个POST请求的路由,增加路由的代码如下:// 定义一个POST请求“/abc”的路由router.post('/abc', function(req, res, next) { console.log (req.body); res.render('index', { title: 'Express' }); // 渲染index页面});

因为POST请求不能直接在浏览器中请求,所以需要使用接口测试工具。在这里推荐使用Postman工具,读者可以自行搜索、安装,这里就不赘述了。

安装完成之后,打开Postman,界面如图1-16所示。图1-16 Postman的默认界面

在URL输入栏中输入地址http://localhost:3000/abc,将前面的请求方式改成POST,接着单击后面的Send按钮,界面如图1-17所示。图1-17 通过Postman发送POST请求/abc

为了便于查看,可以将获取的参数直接打印到返回值里。更改路由代码:// 定义一个POST请求“/abc”的路由router.post('/abc', function(req, res, next) { console.log (req.body); res.send(req.body); // 将请求的POST数据返回});

再次单击Send按钮发送请求,返回一个空对象,如图1-18所示。图1-18 通过Postman发送POST请求,返回空对象

上面的代码中,res.send()方法不会渲染页面,而会直接输出传入的参数,以方便查看。

返回空对象是因为没有传入任何参数。现在来增加一些POST参数。Postman增加POST参数的方法是在Body中添加字段和值。

如图1-19所示,当选择Postman中的Body选项卡时,会发现里面提供了很多选项,但最常用的是www-form-urlencoded,因为这是HTTP的POST请求的默认请求数据格式,通常情况下不会更改。图1-19 POST请求的数据格式

在Body中添加一些字段后再来查看结果。

如图1-20所示,在Body中添加了一些参数之后,在下面的返回结果中已经得到了对应的数据。图1-20 通过Postman获取到POST请求参数1.5.4 Request.params属性:获取URL中的自定义参数

在1.5.1节中定义过这样的路由:// 定义一个GET请求router.get('/book/:id', function(req, res, next) { console.log (req.url); // 打印Request.url的值 res.render('index', { title: 'Express' });});

使用Postman发送请求http://localhost:3000/book/2时,可以看到控制台打印出了“/book/2”,也就是说上面定义的这个id变成了请求地址中的2。在这种情况下,其实是可以获取到这个id值的,Express提供了获取这个id的方法,就是Request.params属性。

在上面定义的路由中打印Request.params属性:// 定义一个GET请求router.get('/book/:id', function(req, res, next) { res.send(req.params); // 将Request.params值返回});

这时再次发送请求http://localhost:3000/book/2,可以看到返回结果是“{id:2}”,如图1-21所示。

还可以定义多个参数,将路由代码更改如下:// 定义一个GET请求router.get('/book/:userId/:id', function(req, res, next) { res.send(req.params); // 将Request.params值返回});

再次通过Postman发送请求http://localhost:3000/book/2/3,可以看到返回结果中有多个自定义的URL参数,如图1-22所示。图1-21 获取一个URL自定义参数图1-22 获取多个URL自定义参数

Express把通过URL传入的参数存到了Request.params属性中,同时它又是一个对象,包含所有自定义的URL参数,可以很轻松地获取到任意一个参数。1.5.5 Request.headers属性:获取请求头数据

除了可以获取到请求体的数据之外,Express还能获取到请求头的数据,它们被保存在Request.headers属性中。

更改路由代码:// 定义一个POST请求“/abc”的路由router.post('/abc', function(req, res, next) { res.send(req.headers); // 将请求的请求头返回});

接着在Postman中发送请求,查看结果。如图1-23所示,返回了很多数据,这些数据都是在Postman中默认添加的。请求头中还可以添加一些自定义参数。

如图1-24所示,在请求头中添加了cookie和token字段,在返回结果中也获取到了相应的值。图1-23 在Postman中获取到默认请求头数据图1-24 添加请求头数据1.5.6 Request.cookies属性:获取客户端cookie

在和前端数据交互的时候,有时需要将数据存放在客户端的cookie中,在客户端再次发送请求的时候,后端可以拿到cookie中的值来做一些操作。

上一节提到,从Request.headers中可以获取到cookie,但是获取过来的是字符串,并不太容易操作。Express提供了一种更简单的方式,它将cookie信息保存在了Request.cookies属性中。如果请求不包含cookie,则默认为{}。注意:客户端的cookie是存在于请求头里面的,而并不在请求体中,使用Request.cookies能够获取到cookie,是因为Express做了处理,所以在设置的时候需要到请求的Header中去设置。

将路由代码更改如下:// 定义一个POST请求“/abc”的路由router.post('/abc', function(req, res, next) { res.send(req.cookies); // 将请求的cookie返回});

接着在Postman中添加一个cookie,发送请求,查看结果。如图1-25所示,很轻松地就获取到了客户端请求所带的cookie,并且它很智能地将多个cookie值分开了,变成Request.cookie对象的一个属性。

试读结束[说明:试读内容隐藏了图片]

下载完整电子书

若在网站上没有找合适的书籍,可联系网站客服获取,各类电子版图书资料皆有。

客服微信:xzh432

登入/注册
卧槽~你还有脸回来
没有账号? 忘记密码?