Express
是基于node.js
平台的快速、开放、极简的web
开放框架,它的地位与做用有点相似于前端的jquery
框架。它的英文官网地址为 http://expressjs.com,其对应的中文官网地址为 http://www.expressjs.com.cn 。下面来简单介绍这个框架的用法。html
express
做为一个第三方模块包,一样是经过npm
的方式进行下载,在当前的项目文件夹下,用命令-> npm install express
来完成下载。再经过 const express = require('express');
来完成引包。前端
当使用了express
这个模块包以后,再也不须要引用node
的http
模块,也能提供建立http
服务器的功能。其基本的代码段结构为:node
const express = require('express'); var app = express(); app.get('/',(req,res)=>{ res.send(''); }); app.listen(3000,'192.168.155.1');
引包以后返回一个函数体,将该函数体调用执行以后的返回值用app
来接收。app
相似于建立的那个http
服务器实例,该服务器监听IP地址为192.168.155.1
,端口号为3000
。当浏览器以get
方式访问http://192.168.155.1:3000/
时,调用执行该回调函数。其中res.send()
为express
内部封装的方法,在其内部能够直接写入返回的字符串参数,不用再用res.writeHead()
来设置状态码和mine
类型。jquery
该回调函数内部虽然能够直接使用
express
本身封装的res.send()
方法,不过原生的res.write()
与res.end()
方法仍然可使用。这三种方法内部参数默认填写字符串类型,若是为其余类型的变量,须要使用.toString()
的方法先将其完成类型转换。而且res.send()
与res.end()
均只能出现一次。web
上述代码段当中的app.get('/',(req,res)=>{});
即为一条路由选择,表示当客户端以get
方式访问根目录时,执行该回调函数当中的代码。咱们能够以这种方式进行路由选择的设计,客户端访问服务器能够有多种方式,如get
、post
、add
、delete
等,不过网页端访问通常只有get
与post
这两种方式,其余的方式通常由app
端发起。在浏览器端输入网址、回车、刷新等方式均是默认以get
方式进行访问。使用app.all()
方法则表明处理这个路由下的任何method
请求。express
url
当中的数据示例代码段为:npm
const express = require('express'); var app = express(); app.get('/:name/:age',(req,res)=>{ var a = req.params.name; var b = req.params.age; console.log(a); console.log(b); res.send(); }); app.listen(3000,'192.168.155.1');
则客户端在访问以后的返回结果为:浏览器
url
地址当中不区分字母的大小写以下所示的示例代码:服务器
const express = require('express'); var app = express(); app.get('/ABb',(req,res)=>{ res.send('成功返回!') }); app.listen(3000,'192.168.155.1');
此时客户端以get
方式访问该网址时,不区分字母大小写。app
url
地址当中全部get
方式提交的参数及锚点均会被忽略以下所示的示例代码:
const express = require('express'); var app = express(); app.get('/a',(req,res)=>{ res.send('成功返回!') }); app.listen(3000,'192.168.155.1');
此时客户端访问为http://192.168.155.1:3000/a#?name=qianqian&age=24
时,一样与上述这条路由相匹配,执行其内部的回调函数。
当有客户端访问该服务器时,会根据用户输入的网址与咱们的路由设计的代码进行路由匹配,一旦找到一个匹配的路由中间件以后,则执行其内部的回调函数,以后再也不与后面代码当中出现的路由中间件进行路由匹配。以下所示的示例代码:
const express = require('express'); var app = express(); app.get('/:username/:method',(req,res)=>{ console.log(1); res.end(); }); app.get('/admin/login',(req,res)=>{ console.log(2); res.end(); }) app.listen(3000,'192.168.155.1');
此时当客户端访问http://192.168.155.1:3000/admin/login
时,因为先匹配上了第一个路由,执行内部的回调函数,再也不匹配第二个路由。
若是想让其匹配上多条路由,则在上述的可能匹配上的路由的回调函数当中加入参数next
,并在回调函数体的最后加上next();
便可。示例代码以下所示:
const express = require('express'); var app = express(); app.get('/:username/:method',(req,res,next)=>{ console.log(1); next(); }); app.get('/admin/login',(req,res)=>{ console.log(2); res.end(); }) app.listen(3000,'192.168.155.1');
此时当客户端访问http://192.168.155.1:3000/admin/login
时,因为先匹配上了第一个路由,执行内部的回调函数,接下去再匹配第二个路由,而后执行其回调函数。
因为
express
当中全部路由中间件的书写顺序相当重要,因此咱们在设计路由时,通常把具体的路由写在上面,把抽象的路由写在下面。
app.use()
是一个特殊的路由中间件咱们使用app.get()
或app.post()
等路由中间件进行路由设计时,咱们都是须要对客户端输入的网址进行精确的路由匹配的(最多只能作到忽略url
当中的锚点即get
方式提交的参数数据)。但用app.use()
来进行路由设计时,咱们能够把第一个参数的层级无限扩充下去。示例代码以下所示:
const express = require('express'); var app = express(); app.use('/admin',(req,res)=>{ res.send('成功匹配!') }) app.listen(3000,'192.168.155.1');
此时当客户端访问http://192.168.155.1:3000/admin/new/path
时,也能匹配上这个路由,从而执行内部的回调函数。
此时咱们能够在回调函数内部使用req.originalUrl
、req.baseUrl
、req.path
来获得用户输入的网址当中的各个部分。示例代码以下所示:
const express = require('express'); var app = express(); app.use('/admin',(req,res)=>{ console.log(req.originalUrl); console.log(req.baseUrl); console.log(req.path); res.send('成功匹配!') }) app.listen(3000,'192.168.155.1');
此时当客户端访问http://192.168.155.1:3000/admin/new/path
时,结果为:
当咱们使用app.use()
这个路由中间件时,若是不写网址或写'/'
,则至关于与该指定ip
与指定端口号下的全部网址进行匹配,由于全部网址均可以看作时'/'
的扩展。app.use((req,res)=>{});
。咱们能够在路由表的最后写上app.use((req,res)=>{res.status(404).send('没有这个页面!');});
能够作404页面,当路由表当中全部路由都匹配不上时,则落入该路由项当中。咱们能够用res.status(404).send('没有这个页面!');
这种方式设置指定的状态码。
相似于Apache
之类的传统服务器软件,都默认提供静态服务,有web
容器和根目录的概念。而对于Node.js
来讲,没有web
容器和根目录的概念,因此当使用node.js
来呈递页面时,须要进行顶层路由设计,来把用户访问的url
地址和文件联系在一块儿。但express
提供静态文件的伺服能力。咱们能够用app.use(express.static(target));
来指定用于提供静态资源服务的文件夹,其中target
表示为提供静态资源服务的文件夹的绝对物理地址。
在主文件1.js
的同目录下新建一个public
文件夹。示例代码以下所示:
const express = require('express'); const path = require('path'); var target = path.join(__dirname,'./public'); var app = express(); app.use(express.static(target)); app.listen(3000,'192.168.155.1');
此时咱们在public
文件夹下新建一个index.html
页面:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <h2>提供静态资源服务文件夹当中的首页页面!</h2> </body> </html>
此时public
文件夹为提供静态资源服务的文件夹,当用户端访问http://192.168.155.1:3000
时,默认进入public
文件夹,显示该文件夹当中的index.html
页面。
咱们也能够在app.use()
方法当中加上第一个参数,如app.use('/static',express.static(target));
此时用户须要输入http://192.168.155.1:3000/static
时,才会至关于进入public
文件夹,显示该文件夹当中的index.html
页面。
咱们通常把提供静态资源服务的路由代码写在上面,防止咱们在进行路由表设计时,与现有的路由发生冲突。
这里主要介绍express
与后台模板引擎ejs
的配合能力。咱们将ejs
下载到项目文件夹的node_modules
文件夹当中,在主文件1.js
当中再也不须要使用require
的方式进行引入。只要写app.set("view engine","ejs");
则完成了引包的工做。接下去再在当前目录下新建一个固定文件名为views
的文件夹,把渲染的html
页面放在其中,后缀名改成.ejs
。用res.render("文件名",{数据});
咱们在与主文件1.js
的同目录下新建一个views
文件夹,里面新建一个index.ejs
的文件,内部代码为:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <h2>后台模板引擎:<%= a %></h2> <ul> <% for(var i = 0; i < list.length; i++){ %> <li><%= list[i] %></li> <% } %> </ul> </body> </html>
其中主文件1.js
的示例代码为:
const express = require('express'); var app = express(); app.set("view engine","ejs"); app.get('/',(req,res)=>{ res.render("index",{ a:'ejs', list:['apple','banana','pear','tomato'] }) }) app.listen(3000,'192.168.155.1');
此时结果为:
若是咱们不想使用views文件夹,咱们能够经过
app.set("views","abc");
命令更改默认文件夹的名字。
get
请求的参数在url
当中,在express
当中,再也不须要使用url
模块,直接使用req.query
便可获得客户端经过get
请求发送的参数对象。示例代码以下所示:
const express = require('express'); var app = express(); app.get('/',(req,res)=>{ console.log(req.query); res.send('成功!'); }); app.listen(3000,'192.168.155.1');
post
请求在express
当中不能直接得到,须要使用第三方模块包body-parser
。经过npm
的方式完成模块包的下载以后,经常使用的代码为const bodyParser = require('body-parser');app.use(bodyParser.urlencoded({extended:false}));
,以后便可使用req.body
来获得参数对象。
咱们在views
文件夹当中写下一个form.ejs
表单,示例代码以下所示:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <form action="http://192.168.155.1:3000" method="POST"> <p>姓名:<input type="text" name="name"></p> <p>年龄:<input type="text" name="age"></p> <p><input type="submit" value="提交"></p> </form> </body> </html>
其中主文件1.js
的示例代码为:
const express = require('express'); const bodyParser = require('body-parser'); var app = express(); app.set('view engine','ejs'); app.use(bodyParser.urlencoded({extended:false})); app.get('/',(req,res)=>{ res.render('form'); }); app.post('/',(req,res)=>{ console.log(req.body); res.send('表单提交成功!'); }); app.listen(3000,'192.168.155.1');
此时在启动在服务器以后,客户端输入网址http://192.168.155.1:3000
时,呈递该表单:
当完成表单填写,并提交以后,结果为:
这样就实现了一个post
方式表单提交的功能。
body-parser
是一个轻量级的模块包,仅仅适合处理表单内容的提交,但不能处理文件、图片等多媒体文件的提交。若是客户端提交的表单当中包含文件、图片等,仍是建议使用formidable
模块包进行处理。