基础知识 | node js基础知识

本文详细介绍了Node.js的基础知识,包括js与Node.js的区别、Node.js的执行方式、特点以及常用模块。重点讲解了全局对象、Buffer、模块系统、文件系统模块、http协议以及Express框架的使用。内容涵盖了从创建web服务器到实现文件操作、路由处理、数据库交互等多个方面,是Node.js初学者的实用指南。
摘要由CSDN通过智能技术生成

官方网站 www.nodejs.org

中文镜像网站 www.nodejs.cn

js和node.js的区别

两者有相同的自定义对象和内置对象,不同的宿主对象

js运行在浏览器端,存在多款浏览器,有兼容性问题。用于开发浏览器端交互效果

node.js运行在服务器端,只有一种解释器,没有兼容问题。用于服务器端开发

查看node.js版本号   node -v

node.js的执行方式    

         脚本模式   node   拖拽的脚本文件  

         交互模式   node (然后直接回车)  为标准输出,所以可以直接写a就出来,交互模式下是全局对象

        退出交互模式  两次ctrc+c

node.js特点

     单线程逻辑处理

     非阻塞的异步I/0处理

     事件驱动编程

     无锁机制,不会产生死锁

     支持数万个并发连接

   适合搭建以IO操作为主、响应速度快、易于扩展的网络应用(命令行工具、带有GUI界面的本地应用程序、交互式终端程序、单元测试工具、基于社交网络的大规模、web socket服务器、TCP/UDP套接子程序 客户端javascript编译器)

   不适合cpu密集型应用(深层次的嵌套和递归、复杂加密和解密算法、高可靠性运算、严格内存管理、数据挖掘和数据分析)

node.js要用到的东西

链接:https://pan.baidu.com/s/1KKyAfrzLbaEU_GED63YiYw 
提取码:fbnu 
复制这段内容后打开百度网盘手机App,操作更方便哦

全局对象

global   检查变量和函数是否为全局的,如果是全局可以使用global访问。

浏览器下的全局对象  window 

node.js下每个文件都是在一个模块作用域下,里面的变量和函数都是局部的,可以防止全局污染

  



console 控制台

      log 打印日志

     info 打印消息

    warn 打印警告

    error 打印错误

    time 开始计时

   timeEnd 结束计时

      注意:开始计时和结束计时的内容要保持一致

process 进程

交互模式下

process.arch   查看当前cpu架构

process.platform 查看当前操作系统版本

process.version  查看node.js版本号

process.pid 查看当前node.js进程编号

process.kill()  结束指定编号的进程

Buffer 

缓冲区,缓冲器,内存中存储数据的区域,通常用于存储网络传输的资源。比如腾讯视频中的某个电影,当你用流量看它时,它一般是先缓冲几分钟,看完就释放了,不会下载下来,之后接着往前缓冲。

Buffer.alloc   创建空间,存储数据

.toString()   转为字符串     一个汉字占3个字节

模块

模块是一个独立的功能体

模块经常使用的方式,一个模块引入另一个模块 或者某个模块引入了好几个其他模块

模块类型

他有三种类型,自定义模块,核心模块,第三方模块

require() 是一个函数,用于引入其他的模块,模块之前还需要写上路径,告诉它到哪里去找

                   同一级寻找 ./        上一级../      上上级 ../../

module 当前模块的对象

module.exports 当前模块导出的对象,默认是一个空对象,里面放想要导出的对象

模块自带的两个变量

—filename        当前模块的绝对路径和模块名称

__dirname        当前模块的绝对路径        dir--directory 目录

模块分类

以路径开头 不以路径开头
文件模块 require('./文件名')  用于引入自定义模块 require('官方提供的核心模块')
目录模块 require('./目录名')到目录下寻找package.json文件中main属性对象的文件,一般默认为index.js文件 require("ran')会到同一级目录下的node_modules目录中寻找,如果找不到会一直往上一级目录中的node_modules中寻找;用于引入第三方模块

自定义模块

自己创建的模块

一个js文件就是一个模块,模块的作用域是局部的,不能直接访问

案例1:把eye.js文件引入face.js

案列2:对象

//写法2
module.exports=person;

之后引入直接

const person=require('./person.js');

目录模块

目录下默认为index.js文件    (必须写为index,默认)

如果目录模块中有几个文件,用json文件里的mian来指定要访问的文件

如果不用路径寻找目录模块的话,就使用node_moudles寻找,这种方式不用写路径,直接写目录模块名

核心模块

核心模块 node.js官方提供的

   查询字符串模块 querystring

         查询字符串:浏览器端向服务器端发请求传递数据的一种方式,位于url中,就是浏览器地址中的网址后?后面的内容

      

         查询字符串模块用于操作查询字符串

         

     URL模块

        url:统一资源定位,互联网上任何的资源都有对应url,url由协议、域名/ip地址、端口、路径、查询字符串组成

         http://www.codeboy.com:9999/product_detail.html?name="电脑"&price=10000

         协议      域名/ip地址         端口   /开头为路径           ?开头为查询字符串

        

       parse()  将url解析为对象,可以获取url中的各部分

   

      定时器模块 timer setTimeout  setInterval  

          提供了一组全局的函数,不需要引入模块(只要是全局函数,不需要引入模块)

        一次性定时器

       setTimeout(回调函数,间隔时间)

        清除

        clearTimeout(timer)

        

u定时输出
 

       

删除定时器效果

周期性定时器

setInterval(回调函数,间隔时间)   每隔一段时间调用一次回调函数    回调函数还是不懂

清除

clearInterval(timer)

开启效果和清除效果的结果在一张图上
 

案列:每隔3秒提醒学习,提醒3次后结束

立即执行定时器 setImmediate   

setimmediate(回调函数)

process.nextTick(回调函数)

单线程只有一个主程序,而定时器又是比较耗时的操作,所以会把它放在事件队列里,最后执行。

两个立即执行函数的执行顺序也有区别

    fs文件系统模块

    文件有两种,目录形式 和文件形式

   (1)查看文件状态

        fs.statSync(文件的路径)

              isDirectory() 检查是否为目录,true是目录

               isFile()   检查是否为文件,true是文件

要切换到对应的路径才能成功不会报错
 

判断文件类型

小技巧,切换到对应的位置后,node后面的内容,文件名可以不写全,之后的按tab键自动补齐

(2)(代码)创建 删除目录

     fs.mkdirSync('目录名称');  创建    不能重复创建,创建一次成功后,再运行会报错,文件已经存在

  

fs.rmdirSync('目录名称');  删除目录    删除目录时,目录为空才能成功删除

案列

在主模块(main)中引入一个功能模块file.js,导出一个函数:在3秒钟以后创建1-10,10个目录,在10秒钟以后把10个目录在移除;最后在main.js中调用函数。

3秒钟内创建10个目录
 
案列完整代码
 

(3) 读取目录

 readdirSync(目录的路径)

readdir(目录的路径,回调函数)

  回调函数:用来获取结果

      err:可能产生的错误

     arr:读取到的内容

注意:两者的区别 sync表示同步,没有这4个单词的表示异步。如果执行过程中有耗时的选择异步,一般情况下选择同步。

sync用变量返回结果,没有他的用回调函数返回结果和提示错误出在哪里。

同步

 
异步成功执行

​​​​​

异步执行失败抛出错误
 

(4)查看状态

     fs.stat(目录的路径,回调函数)

(5)覆盖写入

   writeFileSync(文件的路径,数据)  同步

  writeFile(文件的路径,数据,回调函数)

  提示:如果文件不存在,会创建文件然后写入数据,写入时会把原来的内容给覆盖

             如果文件已经存在,则覆盖原来的数据写入

(6)追加写入

    appendFileSync(文件的路径,数据)  同步

   appendFile(文件的路径,数据,回调函数)

提示:如果文件不存在,会创建文件然后写入数据、

         如果文件已经存在,会在文件的末尾写入数据

       追加写入运行几次,增加几次,但他不会自动换行,需要加上符号\n

       但是也会因为编辑器原因而不成功,推荐使用 EditPlus编辑器

     

(7)读取文件

readFileSync(文件的路径)

readFile(文件的路径,回调函数)

读取的结果为buffer格式,需要转换成字符串。可以用String/toString()

(8)删除文件

       unlink(文件的路径,回调函数)

       unlinkSync(文件的路径)

(9)检测文件是否存在

         existsSync(文件路径)   false不存在,true存在

(10)拷贝文件

copyFileSync(源文件路径,目标文件路径(加上起文件名字))

copyFile(源文件路径,目标文件路径,回调函数)

(11)文件流

    createReadStream()  创建可读取的流

   createWriteStream()  创建可写入的流

    on(事件名称,回调函数)   添加事件,事件名称是固定字符串格式,一旦事件触发自动执行回调函数

    pipe() 管道,将读取的流添加到写入流

   

复制文件

​​​​​​

同步和异步

同步:在主线程执行,会阻止后续代码的执行,通过返回值来获取结果

异步:在一个独立的线程执行,不会阻止主程序中后续代码的执行,通过回调函数获取结果。异步是独立的,所以不能保证执行结果跟你你写得顺序一样。

注意;node.js是一个单线程,一般情况是按顺序执行。但当涉及了异步时,就是多线程,异步多线程会先放入事件队列中,等主线程执行玩后,在执行。并且如果这个线程报错也不影响主线程的执行,异步报错通过回调函数把结果返回给主线程,无论结果是成功执行还是报错,都要返回给主线程。

异步时,也就是当多个线程进行时,各做各的,谁先完成谁就第一个出现。同步按顺序执行。

注意:这里和定时器 立即执行的知识点不要搞混

http协议

   浏览器和web服务器之间的通信协议,浏览器发给web服务器是请求,web服务器给浏览器结果为响应

   http协议含有三部分 ,通用头信息(包含响应头信息,请求头信息)响应头信息 请求头信息

   通用头信息 

  Request URL :浏览器向服务器请求的内容

  Request Method 请求的方法  get获取/post 投递

  Status Code 响应的状态码 (http百度百科里有详细的)

         1**   正在响应,还没有结束

          2**  成功的响应

           4**  客户端请求错误

           3**  重定向--跳转到另一个url

            5**  服务器端的错误

  响应头信息 response

    Content-Type 响应的内容类型  html/js/图片...

    Location 跳转的URL

 请求头信息  request

     通用信息里包括了,就不写了

  请求主体

   可有可无,只有传递数据才会出现,比如表单登录时

  

 http模块 创建自己的服务器

  注意:因为你的电脑即当服务器又当客户端,所以容易被电脑的防火墙拦截,所以需要先关闭它。

  关闭防火墙

   window +r 输入control 打开控制面板后,找到防火墙,关闭

  注意:只要修改了就需要保存并重新其启动服务器

ctrl+c 停止服务器端运行

创建web服务器

const app=http.createServer()

设置端口,访问web服务器端口

app.listen(8080);

通过事件接受请求并做出响应

app.on('request',(req,res)=>{

req 请求的对象

req.url  请求的内容  格式为  /login

req.method 请求的方法

res 响应的对象

req.writeHead()   设置响应的状态码和头信息,头信息根据需要写

res.write()  设置响应的内容

res.end()  结束并发送响应

})

//引入http模块
const http=require('http');
//创建web服务器
const app=http.createServer();
//设置端口,用来访问web服务器
//运行了文件,就创造了端口
//在浏览器网页用ip/域名+端口号访问
app.listen(8080);

//接受浏览器的请求并作出响应
//给web服务器端请求的事件
//req请求的对象   res响应的对象
app.on('request',(req,res)=>{
	//这句在后台
	console.log('有人来啦');
	//write 设置响应的内容 显示到浏览器的内容 
	//现在会乱码
	res.write('请问有人在家吗');
	//结束并发送响应  响应内容后必须写结束
	res.end();
})

  

//引入http模块
const http=require('http');
//创建web服务器
const app=http.createServer();
//设置端口,用来访问web服务器
//运行了文件,就创造了端口
//在浏览器网页用ip/域名+端口号访问
app.listen(8080);

//接受浏览器的请求并作出响应
//给web服务器端请求的事件
//req请求的对象   res响应的对象
app.on('request',(req,res)=>{
	//跳转功能
	//设置响应的状态码为302,设置响应属性location
	res.writeHead(302,{
		Location:'http://www.baidu.com'
	});
	//结束并发送
	res.end();
})

//引入http模块
const http=require('http');
//创建web服务器
const app=http.createServer();
//设置端口,用来访问web服务器
//运行了文件,就创造了端口
//在浏览器网页用ip/域名+端口号访问
app.listen(8080);


//404效果
//接受浏览器的请求并作出响应
//req请求的对象   res响应的对象
app.on('request',(req,res)=>{
	//设置响应的状态码为404
	//设置响应到浏览器的内容not found
	res.writeHead(404);
	res.write('not found');
	//结束并发送
	res.end();
})

//引入http模块
const http=require('http');
//创建web服务器
const app=http.createServer();
//设置端口,用来访问web服务器
//运行了文件,就创造了端口
//在浏览器网页用ip/域名+端口号访问
app.listen(8080);


//404效果
//接受浏览器的请求并作出响应
//req请求的对象   res响应的对象
app.on('request',(req,res)=>{
	//获取请求的对象req.url 
	//console.log输出的值在命令行
	console.log(req.url);
	//获取请求的方法 req.method
	console.log(req.method);
	//设置响应的状态码为404
	//设置响应到浏览器的内容not found
	res.writeHead(404);
	res.write('not found');
	//结束并发送
	res.end();
})

练习:创建web服务器,设置端口,根据浏览器的请求做出响应  当请求的url为index/list/stydy/其他 时,

            /index  响应  <h2>这是首页</h2>

            /list    响应文件     1.html  (读取文件内容,设置为响应的内容)

             /study   跳转到 http://www.baidu.com

           其他  响应 404 not found

技巧:查看网页源代码,点开之后ctrl+A 就全选了。

        

//练习:创建web服务器,设置端口,根据浏览器的请求做出响应
 
//引入http
const http=require('http');
const fs=require('fs');
//创建web服务器
const app=http.createServer();
//设置端口
app.listen(8080);


//浏览器搜索时,应该是 http://localhost:8080/index
//接受请求接受响应
app.on('request',(req,res)=>{
	//判断请求的URL,根据请求的url来做出响应
	//content-type utf8 解决乱码
	if(req.url==='/index'){
		res.writeHead(200,{
		'Content-Type':'text/html;charset=utf-8'
		});
		res.write('<h2>这是首页</h2>');
		
	}else if(req.url==='/list'){
		//读取文件
		let data=fs.readFileSync('./1.html');
		//buffer格式
		//console.log(data);
		//把读取到的文件作为响应的内容,自动转为字符串
		res.write(data);
	}else if(req.url==='/study'){
		res.writeHead(302,{
			Location:'http://www.baidu.com'
		});
	}else{
		res.writeHead(404);
		res.write('not found');
	}
	//结束并发送响应
	res.end();
});

第三方模块

第三方模块 是其他人写的,目录模块也是它。

   包和npm

       包:就是一个目录模块,都是第三方模块

npm:用于管理包的工具,包含下载安装、上传、卸载、升级.....

前端开源网站: http://www.npmjs.com

   npm命令

 npm  -v  查看版本号

下载安装 

npm install  包名字  

      完成后,文件夹里会自动多一个node_moudules目录

        版本信息 下载地址 在package_lock.json 里     package.json里也有信息可以看

框架

集成了一整套的解决方案  node-modules,框架属于第三方模块

express框架

中文官网:www.expressjs.com.cn

基于node.js平台,快速、开放、极简的web开发框架
     下载安装 npm install express

创建web服务器

 const express=require('express');   引入express模块

 const app=express(); 创建web服务器

 app.listen(8080)  设置端口

//第三方模块 express框架
//包 node-modules
//引入express
const express=require('express');
//检查是否成功引入,成功出来一大堆东西
//console.log(express);
//创建web服务器
//这种方式什么也不写,也会有提示 cannot get /  本质就是404
const app=express();
//设置端口
app.listen(8080);

路由

浏览器端发来请求,web服务器端根据请求的方法和请求的url来作出特定的响应。eg:登录的请求就有登录的路由,注册的请求对应注册的路由.....

路由包含三部分 :请求的方法、请求的url、回调函数

响应对象 res

       res.send() 设置响应的内容并发送

       res.sendFile()  设置响应的文件并发送,路径需要使用绝对路径  __dirname自动获取绝对路径

        res.redirect()   设置响应的重定向并发送

     

       

     

提示:这里不用写end语句了,因为它自身包括了这个功能

              响应的内容在网页上看到

请求对象 req   

          请求的东西在后台

req.url 获取请求的url

req.method 获取请求的方法

req.query 获取查询字符串传递的数据。格式为对象

       

//第三方模块 express框架
//包 node-modules
//引入express
const express=require('express');
//检查是否成功引入,成功出来一大堆东西
//console.log(express);
//创建web服务器
//这种方式什么也不写,也会有提示 cannot get /  本质就是404
const app=express();
//设置端口
app.listen(8080);


//添加登录的路由
//规定了请求的方法和路由get /login
//只有符合了要求,才会自动执行回调函数
app.get('/login',(req,res)=>{
   console.log('有一个登录的请求');
   //设置响应的内容,并发送
   //响应得到对象 res
   //并且不会乱码
   res.send('登录成功');
});

练习:添加路由,请求方法get,请求的url /index,响应<h2>这就是首页</h2>

      注意:路由是不冲突的,并且不会出现乱码

//第三方模块 express框架
//包 node-modules
//引入express
const express=require('express');
//检查是否成功引入,成功出来一大堆东西
//console.log(express);
//创建web服务器
//这种方式什么也不写,也会有提示 cannot get /  本质就是404
const app=express();
//设置端口
app.listen(8080);


//添加登录的路由
//规定了请求的方法和路由get /login
//只有符合了要求,才会自动执行回调函数
app.get('/login',(req,res)=>{
   console.log('有一个登录的请求');
   //设置响应的内容,并发送
   //响应得到对象 res
   //并且不会乱码
   res.send('登录成功');
});

//练习:添加路由,请求方法get,请求的url /index
//响应<h2>这就是首页</h2>
//路由是不冲突的
app.get('/index',(req,res)=>{
	console.log('有人来啦');
     res.send('<h2>这是首页</h2>');
});


//添加路由
//请求方法:get   请求url:/study
app.get('/study',(req,res)=>{
	//跳转。重定向到另一个url
	res.redirect('http://www.baidu.com');

});


//添加路由/  跳转到/index
//请求方法:get  
//注意/代表浏览器请求后什么也不用写默认为请求/
// /index前面什么也不写,代表在当前url的服务器寻找
app.get('/',(req,res)=>{
res.redirect('/index');
});


//添加路由
//规定 请求方法get 请求路由/list
//规定响应1.html文件
app.get('/list',(req,res)=>{
	//注意:./是相对路径
	//这里需要绝对路径
	//绝对路径找到方法有两种
	//一种,直接在位置复制绝对路径
	//2种,——dirname 获取绝对路径
	//——filename 获取绝对路径加文件名
	res.sendFile(__dirname+'/1.html');
});

练习:编写7.js文件,使用express创建web服务器,设置端口;创建路由(get /search   请求方法为get,q请求的路由为/search),响应网页search.html,里面内容为暴富方法,根据表单提交的请求,创建对应的路由(get /mysearch)并响应搜索成功

//js页面内容

//创建服务器
const express=require('express');
const app=express();
app.listen(8080);

//创建路由
app.get('/search',(req,res)=>{
res.sendFile(__dirname+'/search.html');
});

//根据表单提交的请求,创建对应的路由(get /mysearch)
//响应搜索成功
app.get('/mysearch',(req,res)=>{
	//获取请求的url,请求的方法,自带
	//req.query 直接获取查询字符串传递的数据
    //格式为对象
	console.log(req.query);
	//获取具体的对象
	console.log(req.query.kw);
	res.send('搜索成功');
})
<!-- 这是html页面内容-->

console.log('暴富方法');<br/>
<!-- form 表单提交,会向服务器端发请求 -->
<!-- method 设置请求的方法 get/post -->
<!-- action  设置请求的url-->
<!-- input name属性 设置输入框的名称,获取用户输入的数据-->
<form method="get" action="/mysearch">
 <input type="text" name="kw">
 <input type="submit">
</form>

post方法

练习:添加响应登录网页的路由(get /login),响应用户登录网页login.html 页面内容有用户密码提交,点击提交向服务器发送请求(post /mylogin),响应登录成功

//创建服务器
const express=require('express');
//引入查询字符串模块
const querystring=require('querystring');
const app=express();
app.listen(8080);


//添加路由(get /login),响应网页
//这部是把服务器端的东西发送给网页
app.get('/login',(req,res)=>{
	res.sendFile(__dirname+'/login.html')
})

//根据表单的请求创建对应的路由(post /mylogin)
//这部是把用户输入的值传给服务器端
app.post('/mylogin',(req,res)=>{
	//获取post请求的数据,以流的形式
	//一旦有数据流入服务器端,自动执行回调函数
	req.on('data',(chunk)=>{
		//获取数据,并转为字符串,格式为查询字符串
		let str=chunk.toString();
		console.log(str);
		//将查询字符串解析为对象
		//这里需要引入查询字符串模块,但模块的引入要放在开头
		let obj=querystring.parse(str);
		console.log(obj.kw,obj.pwd);
	});
	res.send('啦啦啦啦啦啦');
})

console.log('登录成功');
<form  method="post" action="/mylogin">
用户:<input type="text" name="kw"></br>
密码:<input type="password" name="pwd"><br/>
<input type="submit" >
</form>

路由传参

在路由那设置形参,用来接受网页的实参

可以多次重新传,不用重新启动服务器

//创建服务器
const express=require('express');
const app=express();
app.listen(8080);


//添加路由 get /package 用户获取包的详情,响应这是包的详情
//:pname 设置形参,用来接受实参
app.get('/package/:pname',(req,res)=>{
	//获取路由传参的数据
	console.log(req.params);
	res.send('这是包的详情')
})

练习:加入购物车的路由(get /shopping),传递商品的编号lid 和数量count,响应添加成功 编号01 数量5

//创建服务器
const express=require('express');
const app=express();
app.listen(8080);


//添加路由 get /package 用户获取包的详情,响应这是包的详情
//:pname 设置形参,用来接受实参
app.get('/package/:pname',(req,res)=>{
	//获取路由传参的数据
	console.log(req.params);
	res.send('这是包的详情')
})

//添加购物车路由 get /shopping
app.get('/shopping/:lid/:count',(req,res)=>{
	//响应到服务器
	console.log(req.params);
	//响应到网页
	res.send(`
	响应成功
	编号:${req.params.lid}
	数量:${req.params.count}
	`);
})

查询字符串 /mysearch?kw=手机 req.query
post传递 流的方式不可见,在form data 可以看见

req.on('data',(chunk)=>{

chunk,格式为buffer,需要转为字符串、查询字符串,在解析为对象访问

})

路由传参 /package/mysql   红色表示传的真正的值

在路由中设置形参接受

红色表示形参,用来接受真正的值,注意多一个实参就要多一个形参

app.get('/package/:pname'(req,res)=>{

req.params  获取路由参数的数据,格式为对象

})

路由器

用来管理路由,把同一个模块下的所有路由归纳在一起,可以给同一个模块下的路由添加统一的前缀。这样便于团队协作维护项目,防止url出现冲突

 路由器需要用到自定义模块

路由器也是express下的内容,所有需要引入这个模块

创建路由器对象

.....

const r=express.Router();

//往路由器对象添加路由

//导出路由器对象

module.export=r;

在web服务器下挂载

app.use(添加的前缀,引入的路由器)     //建议添加的前缀是那个模块名,比如用户模块,就/user

//app.js 主文件
//创建web服务器
const express=require('express');
//引入用户路由器模块user.js
const userRouter=require('./user.js');
//成功打印会出来一堆东西
//console.log(userRouter);
//注意:运行时运行服务器这个主文件 app.js,其他文件都被引入app.js中了
const app=express();
app.listen(8080);

//把路由器挂载到web服务器下
//两个参数
//参数1,给每个路由器添加前缀   
//参数2,引入的路由器
//注意访问网页路由时,要加上自己命名的前缀。
app.use('/user',userRouter);
//user.js 用户模块 副文件

//引入express
const express=require('express');
//创建路由器对象
const r=express.Router();

//在路由器下添加路由  get /list  响应用户列表
//注意:现在访问这个路由的话,网页访问应该这样写127.0.0.1:8080/user/list

r.get('/list',(req,res)=>{
	res.send('用户列表');
});

//应为是给服务器用,所以需要导出
//它在引入到主文件的过程中,为了与其他模块进行区分,加了前缀/user
//导出路由器对象
module.exports=r;

练习:创建商品路由器product.js,添加今天写得路由,导出路由器,在web服务器挂载,挂载前缀/product

//app.js 主文件
//创建web服务器
const express=require('express');
//引入商品路由器模块user.js
const productRouter=require('./product.js');
//console.log(productRouter);   
//注意:运行时的是主文件 app.js,因为其他文件都被引入app.js中了
const app=express();
app.listen(8080);


//把路由器挂载到web服务器下
//添加前缀/product
app.use('/product',productRouter);
//引入express模块
const express=require('express');
//创建路由器对象
const r=express.Router();
//在路由器下添加路由
r.get('/list',(req,res)=>{
	res.send('商品列表');
});
//导出·路由器
module.exports=r;

中间件 middleware

    处于浏览器和路由之间,用于拦截对路由的请求,最终为路由所服务(就是来判断权限,比如允许你进不进,进入程度,用户管理员等)

    中间件分为应用级中间件、路由级中间件、内置中间件、第三方中间件、错误处理中间件

   中间件写在路由器前面,服务器后面

  所以中间件都要添加到服务器下

应用级中间件

  一旦拦截到请求后,会执行一个函数

  app.use(要拦截的路由(/url),回调函数)  函数有三个参数

要拦截的url对应路由中的url

//引入express模块
const express=require('express');
//创建web服务器
const app=express();
app.listen(8080);


//添加中间件,拦截对路由的请求
//两个参数
//参数1 要拦截的路由
//参数2 写回调函数,一旦拦截到自动执行
//app.use('/list',()=>{
	//在后台服务器显示
	//console.log('拦截了对list的请求');
//});



//中间件
//中间件有三个参数
app.use('/list',(req,res,next)=>{
	//获取查询字符串传递的数据
	console.log(req.query);
//如果用户名不是root,响应请提供管理账户
//否则是管理员,往后继续执行,有可能是下一个中间件或者路由
if(req.query.name!=='root'){
	res.send('请提供管理员账户');
}else{
	//next表示往后执行它后面的路由,这个必须写
	next();
}	
});

练习:添加 加入购物车路由(get shopping),传递商品的价格(price);在中间件中将价格打9折;最后在路由中响应商品的价格:xxx

          传递数据使用查询字符串

  提示:查询字符串是自己直接在网页上写 ?名称=值

//引入express模块
const express=require('express');
//创建web服务器
const app=express();
app.listen(8080);


//商品中间件
app.use('/shopping',(req,res,next)=>{
	//打折之前的价格
	console.log(req.query);
	//获取价格,并打9折
	req.query.price*=0.9;
	//往后执行
	next();
})


//商品路由
app.get('/shopping',(req,res)=>{
 //获取查询字符串传递的数据
 console.log(req.query);
	res.send(`商品的价格为${req.query.price}`);
})
测试了两个值

中间件因为有拦截的路由名称,所以不用担心写几个会搞混

//引入express模块
const express=require('express');
//创建web服务器
const app=express();
app.listen(8080);


//添加中间件,拦截对路由的请求
//两个参数
//参数1 要拦截的路由
//参数2 写回调函数,一旦拦截到自动执行
//app.use('/list',()=>{
	//在后台服务器显示
	//console.log('拦截了对list的请求');
//});



//中间件
//中间件有三个参数
app.use('/list',(req,res,next)=>{
	//获取查询字符串传递的数据
	console.log(req.query);
//如果用户名不是root,响应请提供管理账户
//否则是管理员,往后继续执行,有可能是下一个中间件或者路由
if(req.query.name!=='root'){
	res.send('请提供管理员账户');
}else{
	//next表示往后执行它后面的路由,这个必须写
	next();
}	
});

//商品中间件
app.use('/shopping',(req,res,next)=>{
	//打折之前的价格
	console.log(req.query);
	//获取价格,并打9折
	req.query.price*=0.9;
	//往后执行
	next();
})

//在web服务器上添加用户列表路由(get /list), 响应这是用户列表
app.get('/list',(req,res)=>{
	res.send('这是用户列表');
});

//商品路由
app.get('/shopping',(req,res)=>{
 //获取查询字符串传递的数据
 console.log(req.query);
	res.send(`商品的价格为${req.query.price}`);
})

路由级中间件

路由器的使用

app.use('要拦截的路由前缀(就是要拦截的那个模块,比如用户模块/user)',拦截模块下的路由(比如用户模块下的用户路由/list))

内置中间件

  托管静态资源  (html/css/js/图像....)

  浏览器向服务器端请求静态资源,不需要添加路由,让浏览器

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值