node.js学习笔记

一、Node.js

概念:Node.js就是一款应用程序,是一款软件,它可以运行JS
作用:开发服务器应用
	 开发工具类应用,如webpack,vite.Bable,
	 开发桌面端应用,如vscode,postman,(electron就是基于node开发桌面端应用的)

二、fs(文件系统)

fs模块可以实现与硬盘的交互,例如文件的创建,删除,重命名,移动,还有文件的写入,读取,以及文件夹的相关操作

文件写入

1、writeFile异步写入

/**
 * 需求:
 * 新建一个文件:
 * writeFile(文件名,待写入的数据,选项设置(可选),写入回调)
 */
const fs=require('fs')//require是nodd.js环境中的全局变量,用来导入模块
fs.writeFile('./坚持运动.txt','今天运动了四十分钟',err=>{
    if(err){
        console.log("写入新文件失败")
        return
    }
    console.log("新建文件成功")
})

2、writeFileSync同步写入
fs.writeFileSync(’./data.txt’,‘test’)
3、追加写入

const fs=require("fs")
//1
fs.appendFile('./坚持运动1.txt',',希望可以保持',err=>{
    if(err){
        console.log("追加失败")
        return
    }
    console.log("追加成功")
})
//2
fs.appendFileSync('./坚持运动1.txt',',123')

//3,但会吧之前的内容清空
fs.writeFile('./坚持运动1.txt',',希望可以保持',err=>{
    if(err){
        console.log("追加失败")
        return
    }
    console.log("追加成功")
})
//4,不会把之前的内容清空
fs.writeFile('./坚持运动1.txt',',希望可以保持56789',{flag:'a'},err=>{
    if(err){
        console.log("追加失败")
        return
    }
    console.log("追加成功")
})

4、 createWriteStream流式写入
程序打开一个文件是需要消耗资源的,流式写入可以减少打开关闭文件的次数,流式写入方式适用于大文件写入或者频繁写入的场景,writeFile适合于写入频率较低的场景
当需要持久化保存数据的时候,应该想到文件写入

const fs=require('fs')
let ws=fs.createWriteStream('./node学习.txt')
ws.write('流式写入1\r\n');
ws.write('流式写入2\r\n');
ws.write('流式写入3\r\n');
ws.write('流式写入4\r\n');
ws.end();

文件读取

1、readFile异步读取

const fs=require("fs")
fs.readFile('./node学习.txt',(err,data)=>{
    if(err){
        console.log("读取失败")
        return
    }
    console.log(data.toString())
})

2、readFileSync异步读取

const fs=require("fs")
let data=fs.readFileSync('./node学习.txt')
console.log(data.toString())

3、createReadStream流式读取

const fs=require("fs")
//创建读取流对象
const rs=fs.createReadStream('../node视频.mp4');
//绑定data事件,chunk:块儿,大块
rs.on('data',chunk=>{
    console.log(chunk)
})
//end可选事件
rs.on('end',()=>{
    console.log("读取完成")
})

应用场景:电脑开机,程序运行,编辑器打开文件夹,查看图片,播放视频,播放音乐,git查看日志,上传文件,查看聊天记录

文件复制

const fs=require("fs")
let data=fs.readFileSync('./被复制.txt');
fs.writeFileSync('./hahha.txt',data)
//方式2,流式操作
const rs=fs.createReadStream('./被复制.txt')
const ws=fs.createWriteStream('./新文件.txt')
rs.on('data',chunk=>{
    ws.write(chunk)
})

文件重命名和移动

//重命名
fs.rename('./data.txt','./read.txt',err=>{
    if(err){
        console.log("操作失败")
        return
    }
    console.log("操作成功")
})
//移动
fs.rename('./data.txt','../study/data.txt',err=>{
    if(err){
        console.log("操作失败")
        return
    }
    console.log("操作成功")
})

文件删除

fs.unlink('./data.txt',err=>{
    if(err){
        console.log("删除失败")
        return
    }
    console.log("删除成功")
})
fs.unlinkSync('./data.txt')
//调用rm方法
fs.rm('./data.txt',err=>{
    if(err){
        console.log("删除失败")
        return
    }
    console.log("删除成功")
})

文件夹操作

const fs=require('fs')
//创建文件夹 mk make制作 dir directory 文件夹
fs.mkdir('./data',err=>{
    if(err){
        console.log("创建失败")
        return
    }
    console.log("创建成功")
})
//递归创建    创建文件夹a,a包含文件夹b,b包含文件夹c
fs.mkdir('./a/b/c',{recursive:true},err=>{
    if(err){
        console.log("创建失败")
        return
    }
    console.log("创建成功")
});
//读取文件
fs.readdir('./',(err,data)=>{
    if(err){
        console.log("创建失败")
        return
    }
    console.log(data)
})
//删除文件
fs.rmdir('./data',err=>{
    if(err){
        console.log("删除失败")
        return
    }
    console.log("删除成功")
})
//递归删除 不建议使用,可能被废除
fs.rmdir('./a',{recursive:true},err=>{
    if(err){
        console.log("删除失败")
        return
    }
    console.log("删除成功")
})
//建议使用
fs.rm('./a',{recursive:true},err=>{
    if(err){
        console.log("删除失败")
        return
    }
    console.log("删除成功")
})

查看资源状态

//stat 方法 status 缩写状态
fs.stat('./data.mp4',(err,data)=>{
    if(err){
        console.log("创建失败")
        return
    }
    console.log(data)
    console.log(data.isFile())//资源是否为文件
    console.log(data.isDirectory());//资源是否为文件夹
})

批量重命名

在这里插入图片描述

const fs=require('fs')
const files=fs.readdirSync('./code')
files.forEach(item=>{
    let data=item.split("-");
    console.log(data)
    let [num,name]=data
    if(Number(num)<10){
        num='0'+num
    }
    //新文件名
    let newName=num+'-'+name;
    //重命名
    fs.renameSync(`./code/${item}`,`./code/${newName}`)
})

三、Buffer

概念:

Buffer是一个类似与数组的对象,用于表示固定长度的字节序列
Buffer本事是一段内存空间,专门用来处理二进制数据

特点

Buffer大小固定且无法调整
性能较好,可以直接对计算机内存进行操作
每个元素的大小为1字节(byte)

创建

1.let buf=Buffer.alloc(10)
2.let buf1=Buffer.allocUnsafe(10)//可能会包含旧的内存数据,但速度快,不需要做归零的操作
let buf2=Buffer.allocUnsafe(10000)
console.log(buf)
console.log(buf1)
console.log(buf2)//可以看出有一些旧的数据
<Buffer 00 00 00 00 00 00 00 00 00 00>
<Buffer 00 00 00 00 00 00 00 00 18 d9>
<Buffer 20 19 2b da 1d 02 00 00 d0 ec 2a da 1d 02 00 00 00 20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ff ff ... 9950 more bytes>

3.let buf3=Buffer.from('hello')
console.log(buf3)
<Buffer 68 65 6c 6c 6f>

四、path模块

const path=require('path')
//resolve 拼接规范的绝对路径 常用
console.log(path.resolve(__dirname,'./index.html'))
不常用的暂时没记录,仅作了解
相关知识点补充:

__dirname:用来动态获取当前文件模块所属目录的绝对路径
console.log(_dirname+'./index.html')//D:\nodeJS\13-path\代码/index.html
1./是当前目录
2../是父级目录
3/是根目录(表示一下子回到最顶端的那个文件夹下)

五、HTTP协议

基础知识

HTTP协议的默认端口是80 HTTPS的默认端口是443
本地回环IP地址:127.0.0.1指向当前本机
127.0.0.1~127.255.255.254这个区间内的都可以被称为本地回环IP地址
端口的主要作用:实现不同主机应用程序之间的通信

//创建HTTP服务端
const http=require('http')
//创建服务对象
const server=http.createServer((request,response)=>{
	//设置响应头
	response.setHeader('content-type','text/html;charset=utf-8');
	//设置响应状态码
	response.statusCode=404//响应体的设置
	response.write('xuexi")
	//设置响应体
	response.end('hello http server')
    //获取请求的方法
    console.log(response.method)
    //获取请求的URL
    console.log(response.url)
    //获取HTTP协议的版本号
    console.log(response.httpVersion)
    //获取HTTP的请求头
    console.log(response.headers.host)
    
});
//监听端口,启动服务
server.listen(9000,()=>{
    console.log('服务已经启动')
})
//通过本地回环地址加上端口号9000,可以在浏览器中查看到hello http server

举个栗子

按照以下要求搭建HTTP服务

请求类型/请求方法请求地址响应体结果
get/login登录页面
get/homehome界面
//创建HTTP服务端
const http=require('http')
//创建服务对象
const server=http.createServer((request,response)=>{
	//当响应体中有中文时,会乱码,需要加上下面这行代码
	response.setHeader('content-type','text/html;charset=utf-8');
    let {method} =request;
    let {pathname}=new URL(request.url,'http://127.0.0.1')
    if(method=='GET'&&pathname=='/login'){
        response.end('登录页面')
    }else if(method=='GET'&&pathname=='/home'){
        response.end('home界面')
    }else{
        response.end('Not Found')
    } 
});
//监听端口,启动服务
server.listen(9000,()=>{
    console.log('服务已经启动')
})

设置资源类型(mime类型)

媒体类型,用来表示文档、文件或字节流的性质和格式。
HTTP 服务可以设置响应头 Content-Type 来表明响应体的 MIME 类型,浏览器会根据该类型决定如何处理资源

html: 'text/html',
css: 'text/css',
js: 'text/javascript',
png: 'image/png',
jpg: 'image/jpeg',
gif: 'image/gif',
mp4: 'video/mp4',
mp3: 'audio/mpeg',
json: 'application/json'

六、Node.js模块化

什么是模块化与模块 ?

将一个复杂的程序文件依据一定规则(规范)拆分成多个文件的过程称之为 模块化

//声明函数
function tiemo(){
console.log('贴膜....');
}
//暴露数据
module.exports = tiemo;

//导入模块
const tiemo = require('./me.js');
//调用函数
tiemo();
module.exports 、 require 是 CommonJS 模块化规范中的内容。
Node.js 是实现 CommonJS 模块化规范,他们的关系就像 JavaScriptECMAScript
模块化还有另一种方式就是通过ES6importexport
// 统一暴露
function fun() {
    console.log('fun()');
}

function fun2() {
    console.log('fun2()');
}
export { fun, fun2 }
//引入
import {fun, fun2} from './module2.js'

七、express框架

npm init 初始化创建package.json文件

路由的使用

官方定义: 路由确定了应用程序如何响应客户端对特定端点的请求 一个路由的组成有 请求方法 , 路径 和 回调函数 组成

const express =require('express')
//创建应用对象
const app=express()
//创建路由
app.get('/home',(req,res)=>{
    res.end('hello !!!!')
})
app.get('/',(req,res)=>{
    res.end('首页')  //例如访问http://127.0.0.1:3000时
})
app.listen(3000,()=>{
    console.log("监听端口3000")
})

以上是get 请求,那如果想发送一个post请求呢?我们先来试一下:

app.post('/login',(req,res)=>{
    res.end('post请求')  
})

在这里插入图片描述
发现行不通,这样(http://127.0.0.1:3000/login)通过在地址栏里敲击回车的方法是get请求
为了让回调函数执行,可以通过axios或表单发送一个post请求,

    <body>
        <form method="post" action="http://127.0.0.1:3000/login">
            <button>登录</button>
        </form>
    </body>
	app.post('/login',(req,res)=>{
	    res.end('post请求')  
	})//通过这种方式可以成功发送一个post请求

除此之外还有一些特殊的情况

//匹配所有的请求方法
app.all('/search', (req, res) => {
res.send('333');
});

//自定义 404 路由
app.all("*", (req, res) => {
res.send('<h1>404 Not Found</h1>')
});

express响应设置

//1. express 中设置响应的方式兼容 HTTP 模块的方式
res.statusCode = 404;
res.statusMessage = '11';
res.setHeader('abc','22');
res.write('33');
res.end('44');
//2. express 的响应方法
res.status(500); //设置响应状态码
res.set('xxx','55');//设置响应头
res.send('66');//设置响应体
//连贯操作
res.status(404).set('xxx','77').send('88')
//3. 其他响应
res.redirect('http://atguigu.com')//重定向  如图一
    //app.get('/search', (req, res) => {
	//	res.redirect('https://www.baidu.com/')//chong
	//});
res.download('./package.json');//下载响应
res.json();//响应 JSON   图二
res.sendFile(__dirname + '/home.html') //响应文件内容

在这里插入图片描述
在这里插入图片描述

中间件

中间件(Middleware)本质是一个回调函数 中间件的作用 就是 使用函数封装公共操作,简化代码
中间件的类型:全局中间件、路由中间件

  • 全局中间件
全局中间件:每一个请求 到达服务端之后 都会执行全局中间件函数

下面是一个模拟后端日志的功能
const express =require('express')
const fs =require('fs')
const path =require('path')
//创建应用对象
const app=express()
function recordMiddleware(req,res,next){
    let {url,ip}=req;
    //将信息保存在文件中access.log
    fs.appendFileSync(path.resolve(__dirname,'./access.log'),`${url} ${ip}${new Date()}\r\n`)
    next();
}
app.use(recordMiddleware);
app.listen(3000,()=>{
    console.log("监听端口3000")
})

在这里插入图片描述

  • 路由中间件
/admin  /other 的请求,要求URL携带code=522参数,如未携带提示错误

const express =require('express')
//创建应用对象
const app=express()
let checkCodeMiddleware=(req,res,next)=>{
    //判断URL中是否code==522
    if(req.query.code==='522'){
        next()//符合条件后执行下一步
    }else{
        res.send('错误')
    }
}
app.get('/admin',checkCodeMiddleware,(req,res)=>{
    res.send('首页')
})
app.get('/other',checkCodeMiddleware,(req,res)=>{
    res.send('其他界面')
})
app.listen(3000,()=>{
    console.log("监听端口3000")
})
  • 静态资源中间件
    (静态资源--指内容长时间不发生改变的资源)
app.use(express.static('./public')); //该目录中都是一些静态资源
访问该文件夹下的图片可通过 127.0.0.1:3000/image/logo.png
注意:public下的index.html 文件为默认打开的资源
      路由响应动态资源,静态资源中间件响应静态资源

获取请求体数据 body-parser

//express 可以使用 body-parser 包处理请求体
//npm i body-parser
const bodyParser = require('body-parser');
//获取中间件函数
//处理 querystring 格式的请求体
let urlParser = bodyParser.urlencoded({extended:false}));
//处理 JSON 格式的请求体
let jsonParser = bodyParser.json();
第四步:设置路由中间件,然后使用 request.body 来获取请求体数据

app.post('/login', urlParser, (request,response)=>{
//获取请求体数据
//console.log(request.body);
//用户名
console.log(request.body.username);
//密码
console.log(request.body.userpass);
response.send('获取请求体数据');
//获取到的请求体数据:
[Object: null prototype] { username: 'admin', userpass: '123456' }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值