node.js

目录

一、Buffer

1、创建

2、与字符串的转化

3、读写

二、fs模块

1、文件写入

(1)、异步写入

(2)、同步写入

(3)、追加写入

(4)、流式写入

2、文件读取

(1)、异步读取

(2)、同步读取

(3)、流式读取

3、文件移动和重命名

4、文件删除

5、文件夹操作

(1)、创建

(2)、读取

(3)、删除

6、查看资源状态

7、相对路径问题

8、__dirname

三、path模块

四、HTTP模块

1、创建HTTP服务

2、获取HTTP请求的请求报文

3、获取请求路径与查询字符串

(1)、方式一

(2)、方式二

​编辑

(3)、练习

4、设置 HTTP 响应报文

(1)、使用

 (2)、练习

5、静态服务搭建

6、网页中的url

(1)、绝对路径

(2)、相对路径

7、设置资源类型(mime类型)

8、解决乱码问题

9、错误处理

10、GET和POST

五、node.js模块化

1、模块暴露数据/导出

2、导入模块

3、导入模块的基本流程

六、包管理工具

1、npm基本使用

(1)、初始化包

(2)、搜索包

(3)、安装包

(4)、生产依赖与开发依赖

(5)、全局安装

(6)、修改 windows 执行策略

(7)、安装包依赖

(8)、安装指定版本的包

(9)、删除依赖

(10) 、配置命令别名

(11)、npm安装淘宝镜像 

2、cnmp

3、yarn

4、创建、发布、更新、删除包

七、nvm

八、express

1、快速上手

2、express路由

(1)、简单使用

(2)、获取请求参数

(3)、获取路由参数

3、express 响应设置

4、express 中间件

(1)、全局中间件

(2)、路由中间件

(3)、静态资源中间件

(4)、获取请求体数据 body-parser

5、防盗链

6、路由模块化

7、模板引擎(ejs)

(1)、快速上手

(2)、列表渲染

(3)、条件渲染

(4)、在express中使用ejs

(5)、express-generator

8、文件上传

(1)、前端上传

(2)、出路文件上传请求

九、express中的会话控制

1、cookie

2、session

3、session 和 cookie 的区别  

4、token(JWT)

十、本地域名


一、Buffer

1、创建

2、与字符串的转化

3、读写

二、fs模块

1、文件写入

(1)、异步写入

// require 是 Node.js 环境中的'全局'变量,用来导入模块
const fs = require('fs');
//将 『三人行,必有我师焉。』 写入到当前文件夹下的『座右铭.txt』文件中
fs.writeFile('./座右铭.txt', '三人行,必有我师焉。', err => {
//如果写入失败,则回调函数调用时,会传入错误对象,如写入成功,会传入 null
if(err){
console.log(err);
return;
}
console.log('写入成功');
});

(2)、同步写入

(3)、追加写入

换行\r\n

fs.appendFile('./座右铭.txt','择其善者而从之,其不善者而改之。', err => {
if(err) throw err;
console.log('追加成功')
});
fs.appendFileSync('./座右铭.txt','\r\n温故而知新, 可以为师矣');

用 writeFile实现追加写入

(4)、流式写入

let ws = fs.createWriteStream('./观书有感.txt');
ws.write('半亩方塘一鉴开\r\n');
ws.write('天光云影共徘徊\r\n');
ws.write('问渠那得清如许\r\n');
ws.write('为有源头活水来\r\n');
ws.end();

2、文件读取

(1)、异步读取

//导入 fs 模块
const fs = require('fs');
fs.readFile('./座右铭.txt', (err, data) => {
if(err) throw err;
console.log(data);
});
fs.readFile('./座右铭.txt', 'utf-8',(err, data) => {
if(err) throw err;
console.log(data);
});

(2)、同步读取

let data = fs.readFileSync('./座右铭.txt');
let data2 = fs.readFileSync('./座右铭.txt', 'utf-8');

(3)、流式读取

语法: fs.createReadStream(path[, options])
参数说明:
  • path 文件路径
  • options 选项配置( 可选
返回值: Object
//创建读取流对象
let rs = fs.createReadStream('./观书有感.txt');
//每次取出 64k 数据后执行一次 data 回调
rs.on('data', data => {
console.log(data);
console.log(data.length);
});
//读取完毕后, 执行 end 回调
rs.on('end', () => {
console.log('读取完成')
})

3、文件移动和重命名

fs.rename('./观书有感.txt', './论语/观书有感.txt', (err) =>{
if(err) throw err;
console.log('移动完成')
});
fs.renameSync('./座右铭.txt', './论语/我的座右铭.txt');

4、文件删除

const fs = require('fs');
fs.unlink('./test.txt', err => {
if(err) throw err;
console.log('删除成功');
});
fs.unlinkSync('./test2.txt');

或使用rm、rmSync进行删除

5、文件夹操作

(1)、创建

fs.mkdir('./page', err => {
if(err) throw err;
console.log('创建成功');
});
//递归异步创建
fs.mkdir('./1/2/3', {recursive: true}, err => {
if(err) throw err;
console.log('递归创建成功');
});
//递归同步创建文件夹
fs.mkdirSync('./x/y/z', {recursive: true});

(2)、读取

//异步读取
fs.readdir('./论语', (err, data) => {
if(err) throw err;
console.log(data);
});
//同步读取
let data = fs.readdirSync('./论语');
console.log(data);

(3)、删除

//异步删除文件夹
fs.rmdir('./page', err => {
if(err) throw err;
console.log('删除成功');
});
//异步递归删除文件夹
fs.rmdir('./1', {recursive: true}, err => {
if(err) {
console.log(err);
}
console.log('递归删除')
});
//同步递归删除文件夹
fs.rmdirSync('./x', {recursive: true})

 递归删除建议使用rm

//异步递归删除文件夹(不推荐)
fs.rm('./1', {recursive: true}, err => {
if(err) {
console.log(err);
}
console.log('递归删除')
});

6、查看资源状态

//异步获取状态
fs.stat('./data.txt', (err, data) => {
if(err) throw err;
console.log(data);
});
//同步获取状态
let data = fs.statSync('./data.txt');
结果值对象结构:
  • size 文件体积
  • birthtime 创建时间
  • mtime 最后修改时间
  • isFile 检测是否为文件
  • isDirectory 检测是否为文件夹
  • ....

7、相对路径问题

8、__dirname

__dirname是文件夹的绝对路径,__filename是文件的绝对路径 

三、path模块

const path = require('path');
//获取路径分隔符
console.log(path.sep);
//拼接绝对路径
console.log(path.resolve(__dirname, 'test'));
//解析路径
let pathname = 'D:/program file/nodejs/node.exe';
console.log(path.parse(pathname));
//获取路径基础名称
console.log(path.basename(pathname))
//获取路径的目录名
console.log(path.dirname(pathname));
//获取路径的扩展名
console.log(path.extname(pathname));

四、HTTP模块

1、创建HTTP服务

//1. 导入 http 模块
const http = require('http');
//2. 创建服务对象 create 创建 server 服务
// request 意为请求. 是对请求报文的封装对象, 通过 request 对象可以获得请求报文的数据
// response 意为响应. 是对响应报文的封装对象, 通过 response 对象可以设置响应报文
const server = http.createServer((request, response) => {
response.end('Hello HTTP server'); //设置响应体并结束响应
});
//3. 监听端口, 启动服务
server.listen(9000, () => {
console.log('服务已经启动, 端口 9000 监听中...');
});  //回调函数在服务启动成功之后调用

http.createServer 里的回调函数的执行时机: 当接收到 HTTP 请求的时候,就会执行 

1. 命令行 ctrl + c 停止服务
2. 当服务启动后,更新代码 必须重启服务才能生效
3. 响应内容中文乱码的解决办法
response.setHeader('content-type','text/html;charset=utf-8');
4. 端口号被占用
Error: listen EADDRINUSE: address already in use :::9000
1 )关闭当前正在运行监听端口的服务 ( 使用较多
2 )修改其他端口号
5. HTTP 协议默认端口是 80 HTTPS 协议的默认端口是 443, HTTP 服务开发常用端口有 3000
8080 8090 9000

2、获取HTTP请求的请求报文

注意事项:
1. request.url 只能获取路径以及查询字符串,无法获取 URL 中的域名以及协议的内容
2. request.headers 将请求信息转化成一个对象,并将属性名都转化成了『小写』
3. 关于路径:如果访问网站的时候,只填写了 IP 地址或者是域名信息,此时请求的路径为『 /
4. 关于 favicon.ico :这个请求是属于浏览器自动发送的请求

3、获取请求路径与查询字符串

(1)、方式一

(2)、方式二

(3)、练习

//1、引入http模块
const http = require("http");
//2、建立服务
const server = http.createServer((request,response)=>{
let {url,method} = request; //对象的解构赋值
//设置响应头信息
//解决中文乱码
response.setHeader("Content-Type","text/html;charset=utf-8")
if(url == "/register" && method == "GET"){
response.end("注册页面");
}else if(url=="/login" && method == "GET"){
response.end("登录页面");
}else{
response.end("<h1>404 Not Found</h1>")
}
})
//3、监听端口
server.listen(8000,()=>{
console.log('服务启动中....');
})

4、设置 HTTP 响应报文

(1)、使用

write 和 end 的两种使用情况:
//1. write 和 end 的结合使用 响应体相对分散
response.write('xx');
response.write('xx');
response.write('xx');
response.end(); //每一个请求,在处理的时候必须要执行 end 方法的
//2. 单独使用 end 方法 响应体相对集中
response.end('xxx');

 (2)、练习

将css文件和js文件分开写,代码优化

5、静态服务搭建

6、网页中的url

(1)、绝对路径

(2)、相对路径

较少使用

7、设置资源类型(mime类型)

不设置content-type浏览器也会自动推断类型,写上更规范 

 

8、解决乱码问题

一般只给html文件设置字符集,其他的资源会根据引用它的html文件的字符集进行解析

content-type中的字符集优先级该与html中的meta标签的字符集

9、错误处理

10、GET和POST

五、node.js模块化

1、模块暴露数据/导出

2、导入模块

const test = require('./me.js');

3、导入模块的基本流程

1. 将相对路径转为绝对路径,定位目标文件
2. 缓存检测
3. 读取目标文件代码
4. 包裹为一个函数并执行(自执行函数)。通过 arguments.callee.toString() 查看自执行函数
5. 缓存模块的值
6. 返回 module.exports 的值

六、包管理工具

1、npm基本使用

(1)、初始化包

npm init

(2)、搜索包

(3)、安装包

# 格式
npm install <包名>
npm i <包名>

(4)、生产依赖与开发依赖

(5)、全局安装

npm i -g 包名

(6)、修改 windows 执行策略

2. 键入命令 set-ExecutionPolicy remoteSigned

3. 键入 A 然后敲回车 👌
4. 如果不生效,可以尝试重启 vscode

(7)、安装包依赖

npm i

(8)、安装指定版本的包

## 格式
npm i <包名@版本号>
## 示例
npm i jquery@1.11.2

(9)、删除依赖

## 局部删除
npm remove uniq
npm r uniq
## 全局删除
npm remove -g nodemon

(10) 、配置命令别名

通过配置命令别名可以更简单的执行命令
配置 package.json 中的 scripts 属性

配置完成之后,可以使用别名执行命令  

npm run server
npm run start

(11)、npm安装淘宝镜像 

方式一

npm config set registry https://registry.npmmirror.com/
//目前是这个镜像

方式二

npm i -g nrm       可能报错,指定版本npm install -g nrm open@8.4.2 --save
nrm use taobao
npm config list

 nrm ls可以查看支持的镜像

2、cnmp

3、yarn

4、创建、发布、更新、删除包

 

七、nvm

命令
说明
nvm list available
显示所有可以下载的 Node.js 版本
nvm list
显示已安装的版本
nvm install 18.12.1
安装 18.12.1 版本的 Node.js
nvm install latest
安装最新版的 Node.js
nvm uninstall 18.12.1
删除某个版本的 Node.js
nvm use 18.12.1
切换 18.12.1 Node.js

八、express

1、快速上手

npm init
npm i express
//1. 导入 express
const express = require('express');
//2. 创建应用对象
const app = express();
//3. 创建路由规则
app.get('/home', (req, res) => {
  res.end('hello express server');
});
//4. 监听端口 启动服务
app.listen(3000, () => {
  console.log('服务已经启动, 端口监听为 3000...');
});

2、express路由

(1)、简单使用

app.<method>(path,callback)
//导入 express
const express = require('express');
//创建应用对象
const app = express();
//创建 get 路由
app.get('/home', (req, res) => {
res.send('网站首页');
});
//首页路由
app.get('/', (req,res) => {
res.send('我才是真正的首页');
});
//创建 post 路由
app.post('/login', (req, res) => {
res.send('登录成功');
});
//匹配所有的请求方法
app.all('/search', (req, res) => {
res.send('1 秒钟为您找到相关结果约 100,000,000 个');
});
//自定义 404 路由
app.all("*", (req, res) => {
res.send('<h1>404 Not Found</h1>')
});
//监听端口 启动服务
app.listen(3000, () =>{
console.log('服务已经启动, 端口监听为 3000');
});

(2)、获取请求参数

//导入 express
const express = require('express');
//创建应用对象
const app = express();
//获取请求的路由规则
app.get('/request', (req, res) => {
  //1. 获取报文的方式与原生 HTTP 获取方式是兼容的
  console.log(req.method);
  //GET
  console.log(req.url);
  ///request?a=10&b=200
  console.log(req.httpVersion);
  //1.1
  console.log(req.headers);
  // {
  //   host: '127.0.0.1:3000',
  //   connection: 'keep-alive',
  //   'sec-ch-ua': '"Chromium";v="124", "Microsoft Edge";v="124", "Not-A.Brand";v="99"',
  //   'sec-ch-ua-mobile': '?0',
  //   'sec-ch-ua-platform': '"Windows"',
  //   'upgrade-insecure-requests': '1',
  //   'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36 Edg/124.0.0.0',
  //   accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
  //   'sec-fetch-site': 'none',
  //   'sec-fetch-mode': 'navigate',
  //   'sec-fetch-user': '?1',
  //   'sec-fetch-dest': 'document',
  //   'accept-encoding': 'gzip, deflate, br, zstd',
  //   'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6'
  // }


  //2. express 独有的获取报文的方式
  //获取查询字符串
  console.log(req.path);
  // /request
  console.log(req.query); // 『相对重要』
  // { a: '10', b: '200' }
  // 获取指定的请求头
  console.log(req.get('host'));
  // /127.0.0.1:3000
  res.send('请求报文的获取');
});
//启动服务
app.listen(3000, () => {
  console.log('启动成功....')
})

(3)、获取路由参数

路由参数指的是 URL 路径中的参数(数据)
app.get('/:id.html', (req, res) => {
    res.send('商品详情, 商品 id 为' + req.params.id);
});

3、express 响应设置

//获取请求的路由规则
app.get("/response", (req, res) => {
//1. express 中设置响应的方式兼容 HTTP 模块的方式
res.statusCode = 404;
res.statusMessage = 'xxx';
res.setHeader('abc','xyz');
res.write('响应体');
res.end('xxx');
//2. express 的响应方法
res.status(500); //设置响应状态码
res.set('xxx','yyy');//设置响应头
res.send('中文响应不乱码');//设置响应体
//连贯操作
res.status(404).set('xxx','yyy').send('你好朋友')
//3. 其他响应
res.redirect('http://atguigu.com')//重定向
res.download('./package.json');//下载响应
res.json();//响应 JSON
res.sendFile(__dirname + '/home.html') //响应文件内容
});

4、express 中间件

(1)、全局中间件

声明中间件函数
let recordMiddleware = function(request,response,next){
//实现功能代码
//.....
//执行next函数(当如果希望执行完中间件函数之后,仍然继续执行路由中的回调函数,必须调用next)
next();
}

使用

app.use(recordMiddleware);
express 允许使用 app.use() 定义多个全局中间件
app.use(function (request, response, next) {
console.log('定义第一个中间件');
next();
})
app.use(function (request, response, next) {
console.log('定义第二个中间件');
next();
})

(2)、路由中间件

app.get('/路径',`中间件函数`,(request,response)=>{
});
app.get('/路径',`中间件函数1`,`中间件函数2`,(request,response)=>{
});

(3)、静态资源中间件

//引入express框架
const express = require('express');
//创建服务对象
const app = express();
//静态资源中间件的设置,将当前文件夹下的public目录作为网站的根目录
app.use(express.static(__dirname + '/public')); //当然这个目录中都是一些静态资源
//如果访问的内容经常变化,还是需要设置路由
//但是,在这里有一个问题,如果public目录下有index.html文件,单独也有index.html的路由,
//则谁书写在前,优先执行谁
app.get('/index.html',(request,response)=>{
respsonse.send('首页');
});
//监听端口
app.listen(3000,()=>{
console.log('3000 端口启动....');
});

(4)、获取请求体数据 body-parser

express 可以使用 body - parser 包处理请求体
第一步:安装
npm i body-parser
第二步:导入 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);
//{ username: 'admin', userpass: '123456' }
//用户名
console.log(request.body.username);
//密码
console.log(request.body.userpass);
response.send('获取请求体数据');
});

5、防盗链

6、路由模块化

创建独立的 JS 文件( homeRouter.js
//1. 导入 express
const express = require('express');
//2. 创建路由器对象
const router = express.Router();
//3. 在 router 对象身上添加路由
router.get('/', (req, res) => {
res.send('首页');
})
router.get('/cart', (req, res) => {
res.send('购物车');
});
//4. 暴露
module.exports = router;
主文件
const express = require('express');
const app = express();
//5.引入子路由文件
const homeRouter = require('./routes/homeRouter');
//6.设置和使用中间件
app.use(homeRouter);
app.listen(3000,()=>{
console.log('3000 端口启动....');
})

7、模板引擎(ejs)

现在前后端分离所以较少使用

(1)、快速上手

npm i ejs

 常用语法

<% code %>
//1.引入ejs
const ejs = require('ejs');
//2.定义数据
let person = ['张三','李四','王二麻子'];
//3.ejs解析模板返回结构
//<%= %> 是ejs解析内容的标记,作用是输出当前表达式的执行结构
let html = ejs.render(‘<%= person.join(",") %>’, {person:person});
//4.输出结果
console.log(html);

(2)、列表渲染

let xiyou   = [ '孙悟空 ' , '唐僧 ' , '猪八戒 ' ];

(3)、条件渲染

(4)、在express中使用ejs

(5)、express-generator

搭建一个框架

方式一安装

npx express-generator

方式二安装

npm install-g express-generator

 

使用

express -e 项目名称
//安装依赖
npm i
//运行
npm start

8、文件上传

(1)、前端上传

(2)、出路文件上传请求

npm i formidable

//处理文件上传
router.post('/portrait', (req, res) => {
  //创建 form 对象
  const form = formidable({ 
    multiples: true ,
    //设置上传文件的保存目录
    uploadDir: __dirname + '/../public/images',
    //保持文件后缀
    keepExtensions: true
  });
  //解析请求报文
  form.parse(req, (err, fields, files) => {
    if (err) {
      next(err);
      return;
    }
    // console.log(fields);// text  radio  checkbox  select
    // console.log(files); // file
    
    //服务器保存该图片的访问 URL
    // /images/8ad3d5e36012212ba7642c000.jpg
    let url = '/images/' + files.portrait.newFilename;// 将来将此数据保存在数据库中
    
    res.send(url);
  });
});

九、express中的会话控制

1、cookie

const express =require('express');
//1. 安装 cookie-parser npm i cookie-parser
//2. 引入 cookieParser 包
const cookieParser = require('cookie-parser');
const app = express();
//3. 设置 cookieParser 中间件
app.use(cookieParser());
//4-1 设置 cookie
app.get('/set-cookie', (request, response) => {
// 不带时效性 浏览器删除就关闭
response.cookie('username','wangwu');
// 带时效性
response.cookie('email','23123456@qq.com', {maxAge: 5*60*1000 });
//响应
response.send('Cookie的设置');
});
//4-2 读取 cookie
app.get('/get-cookie', (request, response) => {
//读取 cookie
console.log(request.cookies);
//响应体
response.send('Cookie的读取');
});
//4-3 删除cookie
app.get('/delete-cookie', (request, response) => {
//删除
response.clearCookie('username');
//响应
response.send('cookie 的清除');
});
//4. 启动服务
app.listen(3000, () => {
console.log('服务已经启动....');
});

获取cookie

npm i cookie-parser

 

 

2、session

const express = require('express');
//1. 安装包 npm i express-session connect-mongo
//2. 引入 express-session connect-mongo
const session = require("express-session");
const MongoStore = require('connect-mongo');
const app = express();
//3. 设置 session 的中间件
app.use(session({
name: 'sid', //设置cookie的name,默认值是:connect.sid
secret: 'atguigu', //参与加密的字符串(又称签名)
saveUninitialized: false, //是否为每次请求都设置一个cookie用来存储session的id
resave: true, //是否在每次请求时重新保存session
store: MongoStore.create({
mongoUrl: 'mongodb://127.0.0.1:27017/project' //数据库的连接配置
}),
cookie: {
httpOnly: true, // 开启后前端无法通过 JS 操作
maxAge: 1000 * 300 // 这一条 是控制 sessionID 的过期时间的!!!
},
}))
//创建 session
app.get('/login', (req, res) => {
//设置session
req.session.username = 'zhangsan';
req.session.email = 'zhangsan@qq.com'
res.send('登录成功');
})
//获取 session
app.get('/home', (req, res) => {
console.log('session的信息');
console.log(req.session.username);
if (req.session.username) {
res.send(`你好 ${req.session.username}`);
}else{
res.send('登录 注册');
}
})
//销毁 session
app.get('/logout', (req, res) => {
//销毁session
// res.send('设置session');
req.session.destroy(() => {
res.send('成功退出');
});
});
app.listen(3000, () => {
console.log('服务已经启动, 端口 ' + 3000 + ' 监听中...');
});

3、session cookie 的区别  

4、token(JWT)

npm i jsonwebtoken
//导入 jsonwebtokan
const jwt = require('jsonwebtoken');
//创建 token
// jwt.sign(数据, 加密字符串, 配置对象)
let token = jwt.sign({
username: 'zhangsan'
}, 'atguigu', {
expiresIn: 60 //单位是 秒
})
//解析 token
jwt.verify(token, 'atguigu', (err, data) => {
if(err){
console.log('校验失败~~');
return
}
console.log(data);
})

十、本地域名

编辑文件 C:\Windows\System32\drivers\etc\hosts

例如

127.0.0.1 www.baidu.com
如果修改失败, 可以修改该文件的权限

  • 19
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值