node.js学习笔记

node.js学习

node.js 是什么

node.js是一款基于Chrome V8内核的javaScript运行环境

下载与安装

官网下载,傻瓜式安装

使用

命令行使用

fs文件系统模块 const fs = require(‘fs’);

定义

fs模块是Node.js官方提供的,用来操作文件的模块,它提供了一系列的方法和属性,用来满足用户对文件的操作需求
例如

  • fs.readFile()方法,用来读取指定文件中的内容
  • fs.writeFile()方法,用来向指定的文件中写入内容

注意:使用该模块需要先导入

读取指定文件中的内容 fs.readFile() 方法

格式:fs.readFile(path[,CharSet],callback);

向指定文件中写入内容

格式:fs.writeFile(file,data[,option],callback)

  • file ==>文件路径字符串
  • data ==> 表示要写入的内容
  • option ==> 写入格式 默认utf8
  • callback ==> 回调函数

处理路径问题

路径拼接错误

因为终端的执行路径,导致动态拼接的路劲为错误路径
解放方案:

  • 1.提供绝对路径
  • 2.__dirname 表示当前目录

path路径模块 const path = require(‘path’);

常用方法

  • path.join() 将多个路径片段拼接成一个完整的路径字符串
  • path.basename() 在路径字符串中将文件名解析出来 可以传递第二个参数,用于删除末尾的字符串
path.basename('\\a\\b\\c\\index.html','html')   //<==这个结果是index

–path.extname 获取文件扩展名

http模块

http模块是node.js官方提供的用来创建服务器的模块.通过http模块提供的http.createServer()方法,就能很方便的把一台普通的电脑,变成一台Web服务器,从而对外提供Web 资源服务

  • 需要导入http模块
  • const http = require('http);

服务器以及相关概念

IP地址

每台计算机的唯一表示
采用点分十进制表示(a,b,c,d)

域名(Domain Name)和域名服务器
端口号

每个web服务都对应唯一的一个端口号,通过这玩意准确识别

创建一个服务器的步骤

//导入模块
const http = require('http');
//创建服务
const server = http.crearServer();
//为服务器绑定请求事件
server.on('request',(req,res)=>{});
//启动服务器
server.listen(80,()=>{
    console.log('port 80 running...')
})

req 请求对象

  • url:地址
  • method:请求类型

res 响应对象

  • end(data):向服务器发送数据并结束本次请求

模块化

遵守对应的规则,把一个大文件拆分成独立并互相依赖的小模块

分类

  1. 自定义模块
  2. 官方模块
  3. 第三方模块

加载

require方法

加载模块时,会执行模块中的代码

作用域

在模块内定义的成员无法被模块外访问

module.exports 对象

在自定义模块中可以使用module.exports对象,将模块中的成员共享出去,供外界使用,外界用require方法导入自定义模块时,得到的就是module.exports所指向的对象

共享成员时的注意点

s使用require()当打导入模块时,导入的结果永远以module,exports指向的对象为准

exports对象

由于module.exports单词写起来比较复杂,为了简化共享成员的代码,Node提供了exports对象。默认情况下,exports和module.exports都指向同一个对象,最终的结果,以module.export指向的对象为准

node.js中的模块规范

Node.js遵循了CommonJS模块化规范,CommonJs中规定了模块的特性,和各模块之间如何相互依赖

CommonJs规定
  1. 每个模块内部,module变量代表当前模块
  2. module变量是一个对象,它的export属性(即module.exports)是对外的接口
  3. 加载某个模块其实就是加载这个模块的module.export属性,require()方法用于加载模块

NPM与包

what is 包

就是第三方模块,叫法不同而已

包的来源

由第三方开发,免费下载使用

why need 包

由于Node.js的内置模块仅仅提供了一些底层的API,导致在基于内置模块进行项目开发的时候,效率很低,包是基于内置模块封装出来的,提供了更高级,更方便的API,极大的提高了开发效率,包和浏览器之间的关系,就类似于Jquery和浏览器内置Api之间的关系

从哪里下载包

如何下载

npm(node package manage)包管理工具
npm install 完整的包名称
npm i 完整的包名称

注意点

  1. 初次装包完成后,在项目文件夹下多一个叫做node_modules的文件夹和package-lock.json的配置文件,其中nodel_modules文件夹用来存放所有已安装到项目中的包。require()导入第三方包时,就是从这个目录中查找并加载包
    package-lock.json配置文件用来记录node_modules目录下的每一个包的下载信息,例如包的版本号,下载地址等

  2. 安装指定版本的包
    默认情况下,会自动安装最新版本的包,如果需要安装指定版本的包,可以在包名后面加上@符号指定需要的版本
    例:

npm i moment@2.22.2
  1. 包的语义化版本规范
    包的版本号是以“点分十进制”定义的,总共有三位数字
  • 第一位:大版本
  • 第二位:功能版本
  • 第三位: bug修复版本

包管理配置文件

  1. 多人协作的问题:第三方的包体积过大,不方便成员之间共享项目源代码
    解决方案:共享时剔除node_modules
  2. 在项目根目录中,创建一个叫做package.json的配置文件,即可用来记录在项目中安装了哪些包,从而方便剔除node_modules目录之后,在团队成员之间共享项目的源代码
  3. npm包管理工具提供了一个快捷命令,可以在执行命令时所处的目录中快速创建package.json这个包管理配置文件
npm init -y

上述命令只能在英文的目录下运行成功,所以项目文件夹的名称一定要使用英文

dependencies节点

dependencies节点专门用来记录安装了哪些包

一次性安装package.json中dependencies记录的所有包

npm i

卸载包

  • uninstall 包名

devDependencies 节点

如果某些包只在项目开发阶段会用到,在项目上线以后就不会用到,则可以放到这个包中

//安装指定的包,并记录到devDependencies节点中
npm i 包名 -D
//注意:上述命令只是简写形式,等价与下面完整的写法
nom install 包名 --save-dev

解决包下载速度过慢的问题

//查询当前的下载路径
npm config get registry
//修改当前的下载路径
npm config set registry = 下载路径 '淘宝:https://registry.npm.taobao.org'
nrm管理镜像源
//安装 -g表示全局可用
npm i nrm -g
//查看所有可用的镜像源
npm ls

包的分类

项目包
  1. 开发依赖包(被记录到devDependencies节点的包,只在开发时候使用)
npm install packageName --save-dev
  1. 核心依赖包(被记录到dependencies节点中的包,开发上线都用)
npm i packageName
全局包

规范的包结构

  1. 包必须以单独的目录存在
  2. 包的顶级目录要包含package.json这个包管理配置文件
  3. package.json中必须包含name,version,main这三个属性,分别表示包的名字,版本号和入口

/* 在导入一个包时,会首先执行main指向的对象*/

开发属于自己的包

初始化包结构
  1. 新建包文件夹,作为包的根目录
  2. 在包根目录中,创建如下三个文件。
  • package.json 包管理配置文件
  • index.js 包的入口文件
  • README.md 包的说明文档
package.js的五个必要属性
{
   "name":"zengzeng",  //包的名称
   "version":"1.0.0",  //包的版本号
   "main":"index.js",   //包的入口
   "description":"这是一个测试用包", //包的描述信息
   "keywords":["zeng","pro"],  //搜索关键字
   "license":"ISC"     //开源许可协议

}
  • 展开预算符 … 将对象中的属性全部展开
包的发布
//进入包的根目录
npm publish //发布包
npm unpublish  //只能删除72小时以内发布的包
//并且24小时以内不允许发布相同名字的包

模块的加载机制

模块在第一次加载后会被缓存,也就是说,即使多次require模块,也不会导致模块中的代码反复执行

  • 内置模块加载优先级最高

自定义模块的加载机制

使用require加载自定义模块时,必须指定./或者…/开头,否则会被当做内置模块或者第三方模块进行加载

引入自定义模块若忽略扩展名会自动补全以下扩展

  1. 确切文件名
  2. .js
  3. .json
  4. .node
  5. 找不到,报错

第三方模块的加载机制

在加载一个第三方模块时。node会先找寻父级目录下的node_modules中查找,如果没有则会在父级的父级目录下的node_modules中查找,以此类推,一直找到盘符的根,如果还没有则报错

目录作为模块的加载机制

当把模块作为模块标识符,传递给require()进行加载的时候有三种加载方式

  1. 在被加载的目录下面查找一个叫做package.json的文件,并寻找main属性作为入口
  2. 找寻目录下的index.js文件
  3. 上二者皆不成功则报错

express的基本使用

参数的获取

req.query 这个属性包含get请求中的所有参数
req.param 这个属性可以动态获取链接中的值
//注意 路由格式('/acb/:d') :后表示动态参数

静态资源托管

express.static(‘要托管的文件夹’)
一般写法
app.use(express.static(‘要托管的文件夹’))
挂载路径前缀
app.use(‘前缀’,express.static(‘要托管的文件夹’))

app.use()这个方法常用于注册全局中间件

nodemon插件

nodemon 命令启动项目实现热重载

路由

每当一个请求到达服务器之后,需要先经过路由的匹配,只有匹配成功之后,才会调用对应的而处理函数,在匹配时,会按照路由的顺序进行匹配,如果请求类型请求的URL同事匹配成功,则Express会将注册请求交给对应的function进行处理
路由的概念

模块化路由

为了方便对路由进行模块化的管理,express不建议将路由直接挂载到app上,应当抽离出来作为单独的文件存在

  1. 创建路由模块对应的.js文件
  2. 调用express.Router()函数创建路由对象
  3. 向路由对象上挂载具体的路由
  4. 使用module.exports向外共享路由对象
  5. 使用app.use()注册路由

中间件

中间件的格式

express的中间件本质上就是一个function处理函数

官方截图

注意:中间件的形参列表中,必须包含next参数。而路由的处理函数只包含req和res参数。

next函数的作用

next函数是实现多个中间件连续调用的关键,它表示把流转关系交给下一个中间件或路由

中间件的作用

多个中间件之间,他们的req和res参数都是相同的,所以上游可以在这两个对象上挂载参数供下游的中间件使用

app.get("/",(req,res,next)=>{
    req.a = "hello"
})
app.get("/",(req,res,next)=>{
    console.log(req.a)      //此时就会得到hello
})

中间件有req,res,next三个参数组成

中间件的注意事项

  1. 一定要在路由之前注册中间件
  2. 客户端发送过来的请求,**可以连续调用多个中间件进行处理
  3. 执行完毕中间件的逻辑之后要记得调用next()函数
  4. 在执行next()不要进行其他的操作
  5. req和res在多个中间件之间是共享的

中间件的分类

  1. 应用级别
    通过app.use()或app.get()或app.post()绑定的中间件
  2. 路由级别
    绑定到Route上的中间件
  3. 错误级别
    捕获并处理全局的异常,这个级别的中间件有四个形参(err,req,res,next)
  4. Express内置
    1. express.static 用于快速托管静态资源的内置中间件。
    2. express.json 用于解析JSON格式的请求体数据
    3. express.urlencoded用于解析URL-encoded格式的请求体数据 需要加上配置参数对象
    //通过use对中间件进行配置
    app.use(express.json())
    app.use(express.urlencoded({extended:false}))
    
  5. 第三方
    由第三方开发的中间件,例如body-parser

自制解析post请求的中间件

//制作一个全局中间件放到最前面
app.use((req,res,next)=>{
    //定义数据字符串
    let str = '';
    //通过监听req的data时间来接收数据
    req.on('data',e=>str+=e);
    //通过监听req的end时间来确认数据接收完毕
    req.on('end',()=>{
        //调用内置模块的qureystring.parse方法将字符串转化为实体对象并赋值给req.body
        req.body = querystring.parse(str);
        //将权限转交出去
        next()

    })
})

跨域问题

CORS(Cross-Origin Resource Sharing,跨域资源共享)由一系列的http响应头组成,这些http响应头决定浏览器是否阻止前端js代码跨域获取资源。

浏览器的同源安全策略默认会阻止网页“跨域”获取资源 。但如果接口服务器配置了CORS相关的http响应头就可以接触浏览器短的跨域访问限制

跨域问题

注意
  1. cors主要在服务器端进行配置。客户端浏览器无需做任何额外的配置,即可请求开启了cors的接口
  2. cors在浏览器中有兼容性。只有支持XMLhttpRequst Level2的浏览器才可正常使用。

身份认证

  1. 服务器端渲染推荐使用Session认证机制
  2. 前后端分离推荐使用JWT认证机制

jwt跨域身份认证

定义

JWI (JSON Web Token) 目前最流行的跨域身份认证解决方案

原理

jwt工作原理

用户访问服务器后,服务器根据相关信息生成一个Token,发送给客户端,客户端存储到本地,在客户端再次访问服务器时,发送token,服务器再解密出token中的信息

JWT的组成部分

jwt通常由三部分组成,分别是Header(头部),Payload(有效荷载),Signature(签名)。中间以.分隔

  • Payload 部分才是真正的用户信息,它是用户信息经过加密之后生成的字符串
  • Header 和Signature是安全性相关的部分,只是为了保证Token的安全性。

20230225173550

使用方式

客户端收到服务器返回的JWT之后通常会将它存储在localStorage或者sessionStorage中。

此后,客户端每次与服务器通信都要带上这个JWT的字符串,从而进行身份认证。推荐的做法是把JWT放在HTTP请求头的Authorization字段中,格式如下:

Authorization:Bearer <token>
两个相关的包
  • jsonwebtoken 用于生成jwt字符串
  • epress-jwt 用户将jwt字符串解析还原成JSON对象

在express中使用jwt

为了保证JWT字符串的安全性,防止JWT在网路传输过程中被别人破解,我们需要专门定义一个用于加密解密的secret密钥

  1. 在生成JWT字符串时需要根据secret加密
  2. 在解析JWT字符串时需要根据secret解密

sign方法

返回一个加密的字符串
三个参数:

  1. 用户的信息对象
  2. 加密的密钥
  3. 配置对象,配置当前有效期 expiresIn

express-jwt

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值