express搭建web服务器、路由、get、post请求、multer上传文件、EJS模板引擎的使用

express官网

postman工具下载地址

 multer的npm文档地址

express模板引擎怎么使用  地址:http://www.expressjs.com.cn/guide/using-template-engines.html

EJS中文文档地址

首先建立一个server.js

之后npm init初始化一下

安装express

npm install express --save

在server.js中写入

var express = require("express");//引入express
var app = express();//创建express实例
app.get("/",function(req,res){//定义路由 还有post delete方法 是express定义的
    res.send("服务器响应")
});
app.listen(3000);
console.log("listening to port 3000")

在运行之前安装一个nodemon插件(全局安装),它可以在服务器代码发生改变时自动启动(方便开发)

npm install -g nodemon

运行

nodemon

nodemon会自动去找server.js文件并且运行,实际上就是执行node server.js

如果服务器入口文件叫app.js,那么可以执行nodemon app启动

之后访问localhost:3000或者http://127.0.0.1:3000就会会看到出现服务器返回的内容:服务器响应!!!好简单的express服务器已经完成了,这比http服务器写路由要简单的多

上诉的服务器res.send(),返回了个字符串,当然也可以返回json,而且返回json时,不用专门用JSON.stringify()来转换,express框架已经可以自动转换了

var express = require("express");//引入express

var app = express();//创建express实例

app.get("/",function(req,res){//定义路由 还有post delete方法 是express定义的
var responseObject = {//也可以是数组 数组也会转化为json
name:"大伟"
}
res.send(responseObject)
}); app.listen(3000);
console.log("listening to port 3000")

也可以把res.send()换成res.json(),前者既可以返回纯文本也可以返回json后者只能返回json

-----------------------------------------------------------------------------------------------------

express路由

var express = require("express");//引入express
var cors = require('cors');
var app = express();//创建express实例
app.use(cors());//为了解决跨域问题
app.get("/profile/:id/:name",function(req,res){//:后面的id和:name,代表是可变的
console.log(req.method);//req.method可以拿到前端请求用的是什么方法
console.dir(req.params);//req.params可以拿到路由上定义的参数值 console.dir是在终端打印出对象的内容
var responseObject =req.method;
res.send("you requested to see a profile page"+req.params.id+req.params.name)
}); app.listen(3000);
console.log("listening to port 3000")

上面定义了/profile/:id/:name这样的路由   那么我们在浏览器访问:localhost:3000/profile/xxx/xxx都可以访问到这个页面  而且在服务端还可以拿到客户端输入的这些值

另外,express的路由 也可以用正则表达式去定义

var express = require("express");//引入express
var cors = require('cors');
var app = express();//创建express实例
app.use(cors());//为了解决跨域问题
app.get("/profile/:id/:name",function(req,res){//:后面的id和:name,代表是可变的
console.log(req.method);//req.method可以拿到前端请求用的是什么方法
console.dir(req.params);//req.params可以拿到路由上定义的参数值 console.dir是在终端打印出对象的内容
var responseObject =req.method;
res.send("you requested to see a profile page"+req.params.id+req.params.name)
}); app.get("/ab?cd",function(req,res){//?代表前面的b可以出现0次或一次
res.send("请求成功")
}) app.listen(3000);
console.log("listening to port 3000")

上面用正则定义的路由 可以匹配abcd  或  acd 但是a22cd就匹配不了,这需要对正则有一定了解

-------------------------------------------------------------------------------------------------------------------------

express服务器端如何取到 查询字符串(也就是url ?后面的内容)

下面来新定义一个接口

var express = require("express");//引入express
var cors = require('cors');
var app = express();//创建express实例
app.use(cors());//为了解决跨域问题 app.get("/",function(req,res){
console.dir(req.query);
res.send(req.query);//拿到查询字符串
}); app.get("/profile/:id/:name",function(req,res){//定义路由
res.send("you requested to see a profile page"+req.params.id+req.params.name)
}); app.get("/ab?cd",function(req,res){//?代表前面的b可以出现0次或一次
res.send("请求成功")
}) app.listen(3000);
console.log("listening to port 3000")

很简单 req.query里面就是查询字符串

---------------------------------------------------------------------------------------------------------------------------------

下面我们说一下express中的post请求

在node基础中,我们用了querystring来处理post请求传来的值,在express中我们用body-parser这个插件来处理post传来的值

首先安装这个插件:

npm install body-parser --save

之后在server.js中写一个post请求

var express = require("express");//引入express
var cors = require('cors');
var bodyParser = require('body-parser');//引入body-parser
var app = express();//创建express实例
app.use(cors());//为了解决跨域问题
app.use(bodyParser.urlencoded({extended:false}));//使用body-parser插件 app.post("/",function(req,res){
console.dir(req.body);//取到post请求传来的数据
res.send("success");
})
app.get("/",function(req,res){
console.dir(req.query);
res.send(req.query);//拿到查询字符串
}); app.get("/profile/:id/:name",function(req,res){//定义路由
res.send("you requested to see a profile page"+req.params.id+req.params.name)
}); app.get("/ab?cd",function(req,res){//?代表前面的b可以出现0次或一次
res.send("请求成功")
}) app.listen(3000);
console.log("listening to port 3000")

我们之前都是用表单来发出post请求的,这次我们用postman来模拟post请求

postman工具下载地址

我们进入postman后在地址栏中输入http://localhost:3000  之后请求方法改成POST,之后选择x-www-form-urlencoded(它与form-data的区别是  form-data可以传输文件)

之后填入key以及value,然后点击send,就可以看到请求的响应了(在body中看)

除了以上方法外,也可以在一个html页面中,用jquery的ajax方法发送post请求:

    function aa(){
$.post(
'http://127.0.0.1:3000/',
{
name: 'admin',
password: '123'
},
function(result) {
console.log(result)
$("#inp").val(result)
}
);
}

上诉服务器用bodyparser.urlencoded({extended:false})中间件,来处理post请求发送的form表单数据的,如果我们发送的是json数据该怎么处理呢?:

var express = require("express");//引入express
var cors = require('cors');
var bodyParser = require('body-parser');//引入body-parser 中间件
var app = express();//创建express实例
app.use(cors());//为了解决跨域问题
// app.use(bodyParser.urlencoded({extended:false}));//使用body-parser插件 urlencoded是处理form表单格式的数据的
app.use(bodyParser.json());//json是处理 json数据的 app.post("/",function(req,res){
console.dir(req.body);
res.send(req.body.name);
})
app.get("/",function(req,res){
console.dir(req.query);
res.send(req.query);//拿到查询字符串
}); app.get("/profile/:id/:name",function(req,res){//定义路由
res.send("you requested to see a profile page"+req.params.id+req.params.name)
}); app.get("/ab?cd",function(req,res){//?代表前面的b可以出现0次或一次
res.send("请求成功")
}) app.listen(3000);
console.log("listening to port 3000")

将urlencoded换成json就可以处理post传来的json格式的数据了!!!

那么怎么让不同接口用不同的中间件处理不同的数据呢?

可以像下面这样:

var express = require("express");//引入express
var cors = require('cors');
var bodyParser = require('body-parser');//引入body-parser 中间件
var app = express();//创建express实例
app.use(cors());//为了解决跨域问题
// app.use(bodyParser.urlencoded({extended:false}));//使用body-parser插件 urlencoded是处理form表单格式的数据的
// app.use(bodyParser.json());//json是处理 json数据的
var jsonParser = bodyParser.json();//处理json数据
var urlencodedParser = bodyParser.urlencoded({extended:false});//处理form表单格式数据 app.post("/",urlencodedParser,function(req,res){//这个接口处理form表单数据
console.dir(req.body);
res.send(req.body.name);
}) app.post("/upload",jsonParser,function(req,res){//这个接口处理json数据
console.dir(req.body);
res.send(req.body.name);
}) app.get("/",function(req,res){
console.dir(req.query);
res.send(req.query);//拿到查询字符串
}); app.get("/profile/:id/:name",function(req,res){//定义路由
res.send("you requested to see a profile page"+req.params.id+req.params.name)
}); app.get("/ab?cd",function(req,res){//?代表前面的b可以出现0次或一次
res.send("请求成功")
}) app.listen(3000);
console.log("listening to port 3000")

-----------------------------------------------------------------------------------------------------------------------------

如何把文件上传到服务器中呢?

这需要一个库multer

Multer 是一个 node.js 中间件,用于处理 multipart/form-data 类型的表单数据,它主要用于上传文件。它是写在 busboy之上非常高效。

注意: Multer 不会处理任何非 multipart/form-data 类型的表单数据。

先安装这个库

npm install --save multer

multer的npm文档地址

先在服务器同目录下写一个form.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<form action="/upload" method="POST" enctype="multipart/form-data">
<h2>图片上传</h2>
<input type="file" name="logo">
<input type="submit" value="提交">
</form>
</body>
</html>

在server.js添加:

var express = require("express");//引入express
var cors = require('cors');
var bodyParser = require('body-parser');//引入body-parser 中间件
var fs = require('fs');//引入文件模块
var multer = require('multer');//文件上传需要用到
var upload = multer({dest:'uploads/'});//指定上传的目录 这里指向当前目录下的uploads目录
var app = express();//创建express实例
app.use(cors());//为了解决跨域问题
// app.use(bodyParser.urlencoded({extended:false}));//使用body-parser插件 urlencoded是处理form表单格式的数据的
// app.use(bodyParser.json());//json是处理 json数据的
var jsonParser = bodyParser.json();//处理json数据
var urlencodedParser = bodyParser.urlencoded({extended:false});//处理form表单格式数据 app.get("/form",function(req,res){//文件上传页面
var form = fs.readFileSync("./form.html",{encoding:'utf8'});
res.send(form);
}) app.post("/upload",upload.single('logo'),function(req,res){//上传文件的接口
res.send({'ret_code':0})
}) app.post("/",urlencodedParser,function(req,res){//这个接口处理form表单数据
console.dir(req.body);
res.send(req.body.name);
}) app.get("/",function(req,res){
console.dir(req.query);
res.send(req.query);//拿到查询字符串
}); app.get("/profile/:id/:name",function(req,res){//定义路由
res.send("you requested to see a profile page"+req.params.id+req.params.name)
}); app.get("/ab?cd",function(req,res){//?代表前面的b可以出现0次或一次
res.send("请求成功")
}) app.listen(3000);
console.log("listening to port 3000")

以上代码 访问form路由,会呈现出表单页面

当选择过文件点击提交后会 请求upload接口,此接口会将客户端传过来的文件转换成二进制文件,放在当前目录的uploads文件下;

以上已经基本完成了文件上传到服务器的功能,但是上传到服务器的文件名称是一大串hash值,分不清楚到底是哪个文件(7e059868d06f6a6d0fafb716c1c4c5cc)

下面我们需要对文件名称和路径进行进一步设置:

server.js

var express = require("express");//引入express
var cors = require('cors');
var bodyParser = require('body-parser');//引入body-parser 中间件
var fs = require('fs');//引入文件模块
var multer = require('multer');//文件上传需要用到
var createFolder = function(folder){
try{
fs.accessSync(folder);//文件可访问性检查 如果这个文件可访问就没事
}catch(e){
fs.mkdirSync(folder);//如果访问不到 就创建个这样的文件
}
}
var uploadFolder = './upload/';
createFolder(uploadFolder);
var storage = multer.diskStorage({//磁盘存储引擎
destination: function (req, file, cb) {//设置存放文件的路径
cb(null, uploadFolder)
},
filename: function (req, file, cb) {//设置文件的名称
cb(null, file.originalname + '-' + Date.now())
}
})
var upload = multer({ storage: storage });
var app = express();//创建express实例
app.use(cors());//为了解决跨域问题
// app.use(bodyParser.urlencoded({extended:false}));//使用body-parser插件 urlencoded是处理form表单格式的数据的
// app.use(bodyParser.json());//json是处理 json数据的
var jsonParser = bodyParser.json();//处理json数据
var urlencodedParser = bodyParser.urlencoded({extended:false});//处理form表单格式数据 app.get("/form",function(req,res){//文件上传页面
var form = fs.readFileSync("./form.html",{encoding:'utf8'});
res.send(form);
}) app.post("/upload",upload.single('logo'),function(req,res){//上传文件的接口
console.dir(req.file);//返回上传过来的文件信息
res.send({'ret_code':0})
}) app.post("/",urlencodedParser,function(req,res){//这个接口处理form表单数据
console.dir(req.body);
res.send(req.body.name);
}) app.get("/",function(req,res){
console.dir(req.query);
res.send(req.query);//拿到查询字符串
}); app.get("/profile/:id/:name",function(req,res){//定义路由
res.send("you requested to see a profile page"+req.params.id+req.params.name)
}); app.get("/ab?cd",function(req,res){//?代表前面的b可以出现0次或一次
res.send("请求成功")
}) app.listen(3000);
console.log("listening to port 3000")

以上就是上传文件功能

这里做一个补充,当我们想把一个html页面返回给前台时,不用必须用fs去读取之后再响应到页面,可以直接用express提供的res.sendFile(__dirname+'/form.html');

app.get("/form",function(req,res){//文件上传页面
res.sendFile(__dirname+'/form.html')
})

------------------------------------------------------------------------------------------------------------------------------

下面说一下模板引擎,那么模板引擎的使用场景是什么呢?

就比如上面的form路由会返回一个html页面到前台,但是我们想把res.params.name这个变量传递给html,将这个变量当做html页面的一部分,这该怎么做呢?下面就用到了模板引擎;

下面来介绍express中的一种模板引擎EJS

先安装一下:

npm install ejs --save

EJS中文文档地址

可以在百度搜一下 express template 看看express模板引擎怎么使用  地址:http://www.expressjs.com.cn/guide/using-template-engines.html

下面来使用一下,

首先更改一下server.js文件中内容

var express = require("express");//引入express
var cors = require('cors');
var bodyParser = require('body-parser');//引入body-parser 中间件
var fs = require('fs');//引入文件模块
var multer = require('multer');//文件上传需要用到
var createFolder = function(folder){
try{
fs.accessSync(folder);//文件可访问性检查 如果这个文件可访问就没事
}catch(e){
fs.mkdirSync(folder);//如果访问不到 就创建个这样的文件
}
}
var uploadFolder = './upload/';
createFolder(uploadFolder);
var storage = multer.diskStorage({//磁盘存储引擎
destination: function (req, file, cb) {//设置存放文件的路径
cb(null, uploadFolder)
},
filename: function (req, file, cb) {//设置文件的名称
cb(null, file.originalname + '-' + Date.now())
}
})
var upload = multer({ storage: storage });
var app = express();//创建express实例
app.use(cors());//为了解决跨域问题
app.set('view engine', 'ejs');//使用模板引擎 我们这里使用ejs模板引擎
// app.use(bodyParser.urlencoded({extended:false}));//使用body-parser插件 urlencoded是处理form表单格式的数据的
// app.use(bodyParser.json());//json是处理 json数据的
var jsonParser = bodyParser.json();//处理json数据
var urlencodedParser = bodyParser.urlencoded({extended:false});//处理form表单格式数据 app.get("/form/:name",function(req,res){//文件上传页面
var person = req.params.name;
res.render('form',{person:person})
}) app.post("/upload",upload.single('logo'),function(req,res){//上传文件的接口
console.dir(req.file);//返回上传过来的文件信息
res.send({'ret_code':0})
}) app.post("/",urlencodedParser,function(req,res){//这个接口处理form表单数据
console.dir(req.body);
res.send(req.body.name);
}) app.get("/",function(req,res){
console.dir(req.query);
res.send(req.query);//拿到查询字符串
}); app.get("/profile/:id/:name",function(req,res){//定义路由
res.send("you requested to see a profile page"+req.params.id+req.params.name)
}); app.get("/ab?cd",function(req,res){//?代表前面的b可以出现0次或一次
res.send("请求成功")
}) app.listen(3000);
console.log("listening to port 3000")

另外,需要在根目录建一个views文件夹,里面建一个form.ejs文件(其实就是html页面,只不过我们可以在里面用ejs的语法)

根据form/:name接口,我们是把一个person变量传给了模板,那么在form.ejs中怎么取到这个person变量呢?:

form.ejs:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<h1><%= person %></h1>
<form action="/upload" method="POST" enctype="multipart/form-data">
<h2>图片上传</h2>
<input type="file" name="logo">
<input type="submit" value="提交">
</form>
</body>
</html>

上面用<%=  %>将person包裹住,就可以取到了

然后运行后,在地址栏输入localhost:3000/form/xxxx

这个xxxx就是person的值,在页面上就可以看到这个值了

-----------------------------------------------------------------------------------------------------------------------

上面简单使用了一下ejs模板引擎,下面我们更深入的去使用一下

我们传递给模板一个对象,里面宝行普通变量,也包含数组,来看看怎么将这些展示出来

先看路由里面怎样定义

app.get("/form/:name",function(req,res){//文件上传页面
var data = {name:"大伟",age:18,arr:["tom","july","bob"]};
res.render('form',{data:data})
})

form.ejs中

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<h1><%= data.name %></h1>
<h2><%= data.age %></h2>
<h3><%= data.arr %></h3>
<ul>
<% data.arr.forEach(function(item){ %>
<li><%= item %></li>
<% }) %>
</ul>
<form action="/upload" method="POST" enctype="multipart/form-data">
<h2>图片上传</h2>
<input type="file" name="logo">
<input type="submit" value="提交">
</form>
</body>
</html>

以上可以通过forEach把数组循环遍历出来

-----------------------------------------------------------------------------------------------------------------------------------------------

下面说一下模板共用问题,为什么要模板共用啊,比如说我们有一个网站,上面有一个导航条,每点击一下导航条会切换一个页面,如果每一个导航条在每个页面都写以一遍会比较繁琐,维护起来也比较麻烦。所以下面就说一下ejs的模板共用

首先我们在views中建立一个文件夹partials,这里面放着一些共用模板,我们在partials文件夹中建立一个header.ejs文件,加入这是一个导航条模板,它会被引入到其它模板中去,

views/partials/header.ejs:

<nav>
<ul>
<li><a href="javascript:">home</a></li>
<li><a href="javascript:">about</a></li>
</ul>
</nav>

现在views中已经有一个form.ejs页面了,现在我们再建立一个about.ejs页面,我们要让form.ejs和about.ejs共用header.ejs模板;

在server.js中 建立对应about页面的路由

app.get("/about",function(req,res){//文件上传页面
res.render('about');
})

views/about.ejs:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<%- include('partials/header.ejs') -%>
</body>
</html>

同样在form.ejs中也这样引入即可

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<%- include('partials/header.ejs') -%>
<h1><%= data.name %></h1>
<h2><%= data.age %></h2>
<h3><%= data.arr %></h3>
<ul>
<% data.arr.forEach(function(item){ %>
<li><%= item %></li>
<% }) %>
</ul>
<form action="/upload" method="POST" enctype="multipart/form-data">
<h2>图片上传</h2>
<input type="file" name="logo">
<input type="submit" value="提交">
</form>
</body>
</html>

这样,form.ejs和about.ejs就共用header.ejs模板了!!!

---------------------------------------------------------------------------------------------------------------------------------

上一篇:前端笔记之NodeJS(三)Express&ejs模板引擎&请求识别


下一篇:使用ejs模板引擎