上一节-node.js学习(8)—npm介绍以及自定义模块的发布
本节我们开始讲解express。首先我们回顾下之前所讲的知识点,主要有三部分。
- nodejs的常用模块;
- 利用nodejs模块搭建后台服务器以及与前台进行数据交互;
- 自定义模块以及npm下载发布;
本节我们开始讲解express。那么express是什么?为什么要用express?
1.express与原生nodejs对比
摘用express中文网介绍,express——基于 Node.js 平台,快速、开放、极简的 Web 开发框架。怎么理解呢?
其实express可以看做原生javascript与jquery的关系,它把一些原生的node模块进行封装,为我们提供更快捷的操作。举个栗子:
在前面第一节node.js学习(1)— http模块的学习中,我们曾利用node系统自带的http模块搭建了服务器,那么我们用express同样来搭建个服务器对比下简洁性。
//原生
const http=require('http');
const server=http.createServer(function(){
console.log('有人来了')
})
server.listen(8080);
//express
const express=require('express');
const server=express();
server.listen(8080)
从上面代码我们可以看出,在搭建服务器上,express是不是比原生的更简单点。当然仅仅从搭建服务器来看,并没有简化多少。在下面express介绍中,我们可以更进一步了解express相对于nodejs的极简性。
2.express获取用户请求
在前面第一节node.js学习(1)— http模块的学习中,我们可以在服务器中接收用户请求,从而进行判断处理然后答复。
const http = require('http');
const server = http.createServer(function (req, res) {
//发送HTTP头部;HTTP状态值:200:OK;内容类型:text/plain;charset=utf-8,这样网页上中文就不会乱码。
res.writeHead(200, {
'Content-Type': 'text/plain;charset=utf-8'
});
switch(req.url){
case '/test1.html':
res.write('1');
break;
default:
res.write('404')
break;
}
res.end();
}).listen(8080);
在改成express之前,我们先了解下载express怎么在服务器中接收请求:
1. server.get('/test', function (req,res){
console.log(req.url) // /test
console.log('只能接收get接口请求');
});
2. server.post('/test1', function (req,res){
console.log(req.url)
console.log('只能接收post接口请求');
});
3. server.use('/test.html', function (req,res){
console.log(req.url) // /test
console.log('任何请求,无论是get、post接口请求还是文件请求等');
});
注:1. 官网还有put、delete方法,因为本人不常用,暂不介绍。
2. 上面代码post请求只有通过接口访问时才会执行,默认在浏览器地址栏访问/test
是get请求,所以不会执行post
3.当匹配/test?name=1时候,打印req.query会输出{name:1},如果路径为/test,打印req.query会输出{}对象。之前原生的需要urlFormatter.parse(req.url,true)
这样的写法才可以拿到参数,很方便吧。
4.从刚才直接使用req.query可以看出express的req和res和原生的并不一样,它只是增加了更方便的方法,以前的参数仍然都在,所以express是非破坏式的(不更改node本身的东西,只增加东西)。jquery也是如此,我们可以使用原生方法,也可以使用jquery方法
了解了express接收请求的方法,那么服务器该如何返回内容呢?之前原生用的是 res.write(字符串)
,那么express呢?
res.send(内容)
注:res.send里面的内容可以是任意类型,而之前res.write必须是字符串。任意类型使得我们不用再用字符串包裹着对象,可以直接放对象,很方便有没有
现在我们对上面原生代码进行改写:
const express=require('express');
const server=express();
server.get('/test', function (req,res){
console.log('get接口请求');
res.send({code:1,msg:'get请求'})
});
server.post('/test1', function (req,res){
console.log('post接口请求');
res.send({code:1,msg:'post请求'})
});
server.use('/test.html', function (req,res){
console.log('访问html文件');
//注:这里当访问test.html并不能直接打开test.html,因为没有做文件类型处理(原生用的是 fs.readFile),后面会进一步讲
解。
});
server.listen(8080)
3.express中间件(即插件)
作为前端人员,一定对jquery这个库再熟悉不过了。那么他之所以能流行这么长时间,难道仅仅是因为对原生js进行了常用模块的封装吗?当然不是,很大一部分原因是其可拓展性,可以基于它使用各种各样的插件。那么同样,express把插件叫做中间件。利用中间件,我们可以做很多事。举个例子:
在之前node.js学习(3)— http模块与fs模块综合的学习中,我们曾用fs与http模块进行了静态资源托管,那么我们使用express进行同样的操作对比下简洁性。首先附上之前的原生代码:
//node.js
const http=require('http');
const fs=require('fs');
const server=http.createServer(function(req,res){
const path='./WWW'+req.url;
fs.readFile(path,function(err,data){
if(err){
res.write('404')
}else{
res.write(data)
}
res.end()
})
}).listen(8080)
使用express托管静态文件,我们使用的是express内置中间件——express.static,在早期express的老版本中需要单独install此中间件,叫"express-static"。下面我们使用此中间件来进行处理。首先目录结构如下图:
const express=require('express');
const server=express();
server.get('/test.html',function(req,res){
res.send('1')
})
server.use('/',express.static('www'))
server.get('/a.txt',function(req,res){
res.send('2')
})
server.listen(8080)
将代码运行下,是可以正确访问接口以及www下的文件。
注:这里是无法访问到test.html文件的,因为js代码从上往下执行,当匹配到/test.html,会执行里面的res.send('1'),后面就不会走server.use('/',express.static('www'))
。而访问a.txt我们是可以正确访问到里面的内容,因为文件托管在其下面。假如我们把server.use('/',express.static('www'))
放到const server=express();
下面,当加载/test.html,就会访问www下的test.html文件了,而不是之前的页面输出1。我们工作中,一般把托管文件放到最下面,这样可以避免接口和文件重名,导致没有访问到接口而访问到文件里面了。
现在我们解释下express.static中间件
默认
server.use('*',express.static('www'))
等同于server.use(express.static('www'))
,即在server.js所在目录下,托管www文件夹中的内容。如果需要在静态资源添加类似
/static
的虚拟前缀,我们可以这样写:server.use('/static',express.static('www'))
,这样我们地址必须为/static/a.txt
才可以访问,/a.txt
是访问不到的。
4.express实战——form表单提交
和之前一样,我们用form表单练习下,目录结构如下:
//form.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<form action="http://localhost:8080/user" method="get">
姓名:<input type="text" name="name">
<input type="submit" value="提交">
</form>
</body>
</html>
//serverForm.js
const express=require('express');
const server=express();
server.get('/user', function (req,res){
console.log('get接口请求');
res.send({code:1,msg:'get请求'})
});
server.post('/user', function (req,res){
console.log('post接口请求');
res.send({code:1,msg:'post请求'})
});
server.use('/',express.static('www'))
server.listen(8080)
下面动图为测试结果,post请求会走到post方法里面,get请求会走到get方法里面。
5.express实战——ajax提交
上面我们讲解了使用form提交并在后台进行数据交互,接着我么使用ajax提交,server代码不用变,只对form进行修改如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
姓名:<input type="text" name="name" class="name">
<button>
提交
</button>
</body>
<script src="jquery-3.3.1.min.js"></script>
<script>
$(document).on('click','button',function(){
const name = $(".name").val();
$.ajax({
type: 'post',
url: '/user',
data: {
'name': name,
},
success: function (data) {
console.log(data); //{code:1,msg:'post请求'}
alert(data.msg)
},
error: function () {
alert('请求错误')
}
})
})
</script>
</html>
结果如下: