我是靠谱客的博主 风中黄蜂,最近开发中收集的这篇文章主要介绍node学习总结,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

什么是Node.js

Node.js是基于Chrome V8引擎的JavaScript运行环境。

终端

终端是专门为开发人员设计的,用于实现人机交互的一种方式。

终端中的快捷键

  • ↑ 小方键盘上 ,可以执行上一次的命令 键盘
  • tab 快速补全路径 键盘
  • esc 清空输入的内容 键盘
  • cla cla清空终端中的内容 字符串

Fs文件系统模块

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

  • fs.readFile()读取指定文件的内容
  • fs.writeFile()写入指定文件的内容

如何导入Fs模块

const fs = require(‘fs’)
代码写在最顶部

fs.readFile(path[options],callback)

// 导入fs模块
const fs = require('fs')
// 使用fs.readFile 方法读取文件
// 参数1 ,文件的路径
// 餐数2,编码格式,一般采用utf8
// 参数3,回调函数
fs.readFile('./12.txt','utf8',function(err,dataStr){
    // 失败  如果成功 err =null
    //      如果失败  dataStr = undefined
    console.log(err);
    // 成功
    console.log(dataStr);
})

fs.writeFile(file,data[options],callback)

const fs = require('fs')
// 参数1  文件路径
// 餐数2 ,传入内容
// 参数3 , 编码格式
// 参数4 ,回调函数
fs.writeFile('./12.txt','Hello','utf8',function(err) {
    if (err!==null){
        console.log('失败')
       
    }
    console.log('成功')
})

fs模块——路径动态拼接

如果使用相对路径./ …/开头的话,可能会导致,文件读取失败,Node是通过拼接字符串的形式来获取路径的
解决方案:
使用相对路径,对需要用node运行的文件右键复制路径,然后通过粘贴进行写入路径,但是在CSS中/表示转义的意思,所以我们需要用//表示
缺点:移植性差,不利于维护
完美解决方案

__dirname :

表示当前文件所处的目录,利用字符串拼接的形式,来提供路径

const fs = require('fs');
fs.readFile(__dirname + '/成绩单.txt','utf8',function(err,dataStr){
    if(err!=null){
        console.log('失败'+err.message);
    }else{
        console.log('成功'+dataStr)
    }
    
    console.log(__dirname);
   
})

path路径模块

导入path模块

const path = require(‘path’);

路径拼接

path.join()语法格式;
path join([…paths])
注意

路径拼接传进去的参数,如果有“…/”会抵消上一层路径

const fs = require('fs');
const path = require('path');
fs.readFile(path.join(__dirname, '/12.txt'),'utf8',function(err,dataStr) {
    if (err){
        console.log(err.message);
    }
    console.log(dataStr);
})

获取路径中的文件名

path.basename(path[,ext]);
第一个参数是 文件的路径
第二个参数是 文件的后缀名,如果选择,后缀名将不会打印

const path = require('path');

const lj = '/files/12.txt'
var houzhui = path.basename(lj);
console.log(houzhui);
var houzhui2 = path.basename(lj,'.txt')
console.log(houzhui2);

获得路径中文件的扩展名

path.extname(path);
就一个参数,文件的路径

const path =require('path');
const lj = './12.txt'
const  kuozhanming = path.extname(lj)
console.log(kuozhanming);

http模块

http模块是Node.js官方提供的,用来创建web服务器的模块,我们可以用http.createServer()方法,就能把一台普通的电脑,变成一台Web服务器。

导入http模块

const http = require('http')

创建Web服务器

创建Web服务实例:
使用http.createServer();方法

绑定request事件,监听需求

启动服务器
使用listen()方法,如果使用80接口,地址后面可以不加入80

// 导入http模板
const http = require('http')
// 创建Web服务器实例
const server = http.createServer();
// 绑定request事件,监听客户端的需求
server.on('request',function(req,res){
    console.log('欢迎')
})
// 启动服务器
server.listen(8080,function(){
    console.log('启动成功 at http://127.0.0.1:8080');
})
 

req请求对象

req请求对象,包含两个参数

req.url 是客服端请求的URL地址
req.method 是客服端的请求类型

// 导入http模板
const http = require('http');
// 创建Web服务器
const server = http.createServer();
// 绑定监听事件
server.on('request',function(req){
    const url = req.url;
    const method = req.method;
    console.log('你的URL地址是'+url,'你的请求类型是'+method)
})
// 启动服务器
server.listen(80,function(){
    console.log('成功启动地址是 http://127.0.0.1')
})

res参数的使用

利用setHeader 解决中文乱码问题

end向客服端返回一些消息

 // 解决中文乱码的问题
    res.setHeader('Content-Type', 'text/html;charset=utf-8')
    // res.end()向客户端响应一些消息
    res.end('你是狗');

动态响应

通过req.url获得用户访问的URL地址,判断URL地址,提示不同的内容

const http = require('http');
// 创建服务器
const server = http.createServer();
// 绑定 request事件
server.on('request',function(req,res){
    const url = req.url;
    let content = '<h1>404 Not found!</h1>';
    if(url==='/'||url==='/index.html'){
        content ='<h1>首页</h1>';
    }else if(url==='/about.html'){
        content = '<h1>关于</h1>';
    }
    res.setHeader('Content-Type','text/html;charset=utf-8');
    res.end(content);
})
// 启动服务器
server.listen(80,function(){
    console.log('启动成功 at http://127.0.0.1')
})

模块化

模块化是指解决一个复杂问题时,自顶向下逐层把系统划分成若干模块的过程。对整个系统来说,模块是可组合,分解和更换的单元。

使用模块化的好处:

  • 提高了代码的复用性
  • 提高了代码的可维护性
  • 可以实现按需加载

模块化的规范

模块化规范就是对代码进行模块化的拆分和组合,需要遵守的规则

Node.js中模块的分类

  • 内置模块(node官方提供的)
  • 自定义模块 (自己创建的)
  • 第三方模块(第三方下载的)

模块作用域

在自定义模块中定义的变量,方法,只能在当前模块被访问,这种级别的访问限制,叫做模块作用域
模块作用于的好处:
防止全局变量污染

向外共享模块作用域中的成员

module对象

在每个JS的自定义模块中都有一个module对象,它里面存储了和当前模块相关的信息

module.exports对象

在自定义模块中,可以使用module.exports对象,将模块内的成员共享出去,供外界使用

// 利用exports对象传递变量和方法
module.exports ={
    uname:'zs',
    sayHello:function(){
        console.log('Hello');
    }
}

什么是包?

包就是第三方模块

npm包

通过 npm i 包名,进行安装
安装以后去npmjs.com 搜索包名,查看文档

快速创建package.join

使用命令 npm init -y

快速安装所有包

npm i

快速卸载包

注意:卸载包没有缩写

nup uninstall

将包安装在devDependencies节点中

如果某些包只在开发阶段用得到,建议安装在devDependencies节点中;
某些包 在开发和项目上线后都用得到,建议安装在dependencies节点中

npm i 包名 -D

包的分类

项目包:
被安装在mode_module目录中的包,叫做项目包
项目包又分为:
开发依赖包 : 存储在devDependencies里面的包 npm i 包名 -D
核心依赖包: 存储在dependencies里面的包 npm i 包名

全局包
提供-g参数
npm i 包名 -g 全局安装包

模块的加载机制

模块在第一次加载后会被缓存。这就是意味着多次调用require()不会被多次执行
注意:
不论是内置模块,用户自定义模块,还是第三方模块,都会优先从缓存中加载,从而提高模块的加载效率

内置模块的加载机制

最高优秀级。如果第三方模块,自定义模块有相同的文件名,会优先加载内置模块

自定义模块的加载机制

先加载指定的文件;
如果找不到,补全.js进行寻找
如果找不到,补全json进行寻找
如果找不到,补全node进行查找

第三方模块的加载机制

会一直往上翻,直到找到为之。
如果一直找不到,就会报错

Express

Express是基于Node.js平台,快速,开放,极简的Web开发框架
Express的本质:第三方的包,提供了快速创建Web服务器的便捷方法

Express的安装

执行命令:
npm i express@4.17.1

快速创建一个Express服务器

先导入模块,在创建服务器,然后调用linsten方法启动服务器

// 导入 express 的模块
const express = require('express');

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

// 调用app.listen启动服务器
app.listen(80,()=>{
    console.log('express server running at http://127.0.0.1')
})

监听get请求

发送固定的数值

app.get('/user',(req, res) => {
    res.send({
        name:"Zs",
        age:20,
        sex:"男"
    })
    // req.query获得客服端发送的参数
    // query是一个空对象
    console.log(req.query)
})

发送客户端传递的数值

app.get('/',(req, res) => {
    // req.query获得客服端发送的参数
    // query是一个空对象
    let a = {
        name:req.query.name,
        age:req.query.age,
    }
    res.send(a)
})

监听POST请求

app.post('/user',(req, res) => {
    res.send('请求成功')
})

get请求动态获取参数

req .params

// get请求动态的获取参数
// res.params
app.get('/abc/:id',(req, res) => {
    res.send(req.params)
})

托管静态资源

express提供了一个非常好用的函数,叫做express.static()通过它,我们可以非常方便的创建一个静态资源服务器。

// 导入express模块
const express = require('express');
// 创建服务器
const app = express();
// 利用express.static将一个文件设置静态托管,使外界可以访问
app.use(express.static('./sbx'))
app.use(express.static('./sz'))
// 如果想托管多个,只需要重复调用express.static这个函数即可
// app.use(express.static('./sbx'))

// 注意:
// 托管多个静态页面时,会根据写入的顺序去查找文件,如果有同名文件,会先调用导入前面的文件夹中的文件

// 启动服务器
app.listen('80',()=>{
    console.log('http://127.0.0.1:80')
})

特别注意:
托管多个文件夹时,同名文件的调用顺序

挂载路径前缀

拼接字符串的形式

app.use('./sbx',express.static('./sbx'))

路由

按键与服务之间的映射关系

Express中的路由

客户端之间的请求与服务器处理函数之间的映射关系
由三部分组成:
请求的类型
请求的URL地址
处理函数

路由的匹配过程

每一个请求到达服务器后,经路由的匹配,匹配成功后,才会调用相关的函数。

模块化路由

创建一个JS文件,存放路由
通过express.Router()创建一个路由
给路由添加get或者POST 响应
将路由对象通过module.exports进行公共化

// 这是路由模块
// 1. 导入 express
const express = require('express')
// 2. 创建路由对象
const router = express.Router()

// 3. 挂载具体的路由
router.get('/user/list', (req, res) => {
  res.send('你是猪')
})
router.post('/user/add', (req, res) => {
  res.send('Add new user.')
})

// 4. 向外导出路由对象
module.exports = router

在主文件中导入
通过app.use进行导入,要先把自定义模块导入其中

const express = require('express')
const app = express()

// app.use('/files', express.static('./files'))

// 1. 导入路由模块
const router = require('./d1')
// 2. 注册路由模块
app.use(router)

// 注意: app.use() 函数的作用,就是来注册全局中间件

app.listen(80, () => {
  console.log('http://127.0.0.1')
})

Express中间件

业务流程中的处理环节
对请求进行预处理
中间件必须包含next参数,去指向下一个中间件或者路由

全局中间件

使用app.use()调用的中间件函数,称为全局中间件

const express = require('express')
const app = express()

// 定义第一个全局中间件
app.use((req, res, next) => {
  console.log('调用了第1个全局中间件')
  next()
})
// 定义第二个全局中间件
app.use((req, res, next) => {
  console.log('调用了第2个全局中间件')
  next()
})

// 定义一个路由
app.get('/user', (req, res) => {
  res.send('User page.')
})

app.listen(80, () => {
  console.log('http://127.0.0.1')
})
// 使用app.use导入的中间件函数,叫做全局中间件,全局中间件函数必须包含next 指向下一个中间件,
// 执行顺序,即书写的顺序

局部中间件

不使用app.use()调用的中间件,通过参数,或者数组的方式在路由中进行调用的中间件称为局部中间件

// 导入 express 模块
const express = require('express')
// 创建 express 的服务器实例
const app = express()

// 1. 定义中间件函数
const mw1 = (req, res, next) => {
  console.log('调用了局部生效的中间件')
  next()
}
const mw2 = (req, res, next) => {
    console.log('调用了局部生效的中间件2')
    next()
  }

// 2. 创建路由
app.get('/', mw1,mw2, (req, res) => {
  res.send('Home page.')
})
app.get('/user', (req, res) => {
  res.send('User page.')
})

// 调用 app.listen 方法,指定端口号并启动web服务器
app.listen(80, function () {
  console.log('Express server running at http://127.0.0.1')
})
// 不使用 app.use调用的中间件。成为局部中间件

中间的注意事项

  1. 必须在路由前注册中间件,如果在路由之后注册中间件,中间件不能正常的使用
  2. 客户端发送过来的请求,可以连续调用多个中间件
  3. 必须包含next参数,调用next()方法去指向下一个中间件或者路由
  4. 调用next()方法后,不建议写任何代码
  5. 连续调用多个中间件,多个中间件共享req和res对象

中间件的分类

应用级别的中间件

  • 通过app.get(),app.post(),app.use()绑定到app实例上的中间件

路由级别的中间件

  • 绑定到router实例上的中间件
  • 绑定到express.Router()实例上的中间件

错误级别的中间件

  • 错误级别中间件的作用:专门用来捕获整个项目发生的异常错误,从而防止项目异常崩溃的问题
  • 错误级别中间件具有4个参数(err,req,res,next)
  • 错误级别的中间件必须在路由之后
const express = require('express');
const app = express();
app.get('/',(req,res)=>{
    throw new Error('服务器发生错误')
    res.send('Hello World')
})
// 错误中间件
app.use(function(err,req, res,next){
    console.log('发生错误'+err.message);
    res.send('发生错误'+err.message);
})

app.listen(80,function(){
    console.log('http://127.0.0.1:80');
})

Express 内置的中间件

在这里插入图片描述

express.json()的使用

const express = require('express');
const app = express();

// 利用内置中间件解析JSON数据
// 必须在配置路由之前
app.use(express.json());

// POST请求 获取数据
app.post('/',(req,res) => {
    console.log(req.body)
    res.send('收到数据')
})
app.listen(80,function(){
    console.log('http://127.0.0.1:80');
})

express.urlencoded()内置中间件

const express = require('express');
const app = express();

// 导入express.urlencoded内置中间件
app.use(express.urlencoded());

// POST请求
app.post('/',(req, res) => {
    console.log(req.body);
    res.send('收到')
})

app.listen(80,function(){
    console.log('http://127.0.0.1:80');
})

第三方中间件

Express写接口

主文件

const express = require('express');
// 创建服务器
const app = express();
// 导入自定义的api模块
const routes = require('./aprRouter')


// 解析表单数据
app.use(express.urlencoded({ extended: false }))
// 注册路由
app.use('/api', routes);

// 启动服务器
app.listen(80,function(){
    console.log('http://127.0.0.1:80')
})

API路由接口文件

const express = require('express')
const routes = express.Router();

// get请求
routes.get('/get',(req,res) => {
    // 拿到客户端发送的数据
    const query = req.query;
    // 响应客户端消息
    res.send({
        status:0,
        msg: 'GET请求成功',
        data:query
    })
})

// post请求
routes.post('/post',(req,res) => {
    // 拿到客户端发送的数据
    // 接受的数据格式为urlencoded  需要解析
    const body = req.body;
    // 响应客户端
    res.send({
        status:0,
        msg: 'POST',
        data:body
    })
})


// 向外展示
module.exports =routes;

接口的跨域问题

CORS (主流解决方案)
JSONP (只支持get请求)

CORS

cors是Express的一个第三方中间件。
下载CORS :npm i cors

// 导入cors 模块
const cors = require('cors')
// 解決跨域问题
app.use(cors());

CORS响应头部 Access-Control-Allow-Origin

语法:

Access-Control-Allow-Origin:<origin>|*

origin参数指定了允许访问该资源的外域URL
例:
下面的代码只能是http://itcast.cn进行访问,其他访问是不返回数据的

res.setHeader('Access-Control-Allow-Origin','http://itcast.cn')

CORS请求的分类

简单请求

  • GET
  • POST
  • HEAD
  • 无定义头部字段

预检请求

  • Method
  • 包含自定义头部字段
  • application/json格式的数据

两者区别

简单请求的特点:客服端和服务器只会发生一次请求
预检请求的特点:客户端和服务器会发生两次请求,预检请求后再发起简单请求

JSONP

浏览器通过《script》”标签的src属性,请求服务器上的数据,同时,服务器返回一个函数的调用。这种请求方式叫做JSONP
特点:
JSONP不属于ajax请求,没有XMLHttpRequest对象
JSONP只支持get请求

数据库

组织 存储 管理数据的仓库

传统型数据库的数据组织结构

在传统型数据库中,数据的组织结构分为数据库,数据表,数据行,字段这4大部分组成

在项目中使用MySQL

先执行安装命令 npm i mysql

// 导入mysql模块
const mysql = require('mysql');
// 建立与mysql数据库的联系
const db = mysql.createPool({
    host:"127.0.0.1", //数据库的地址
    user:'xxxxx',       //账号
    password:'xxxxx', // 密码
    database:'ceshi1'   //操作数据库的名称
})

插入数据

简便的插入数据
const sj = {username:'hh',password:'123456'}
const cryj = 'INSERT INTO users1 SET ?'

db.query(cryj,sj,(err, result) => {
    if (err) return console.log(err.message)
    // if(result.affectedRows===1){
    //     console.log('插入成功')
    // }
    console.log(result)
})

更新数据

const sj = {id:6,username:'xx',password:'456'}
const gxyj = 'UPDATE users1 SET ?  WHERE id=6'

// 调用函数

db.query(gxyj,sj,(err, result) => {
    if (err) return console.log(err.message);
    if(result.affectedRows===1){
        console.log('更新成功')
    }
})

删除数据

const scsj = 'DELETE FROM users1 WHERE id=6';
// 调用函数

db.query(scsj,(err, result) => {
    if (err) return console.log(err.message);
    if(result.affectedRows===1){
        console.log('删除成功')
    }
})

注意

如果使用result 判断数据是否成功的更新,删除。result是一个对象,所以我们可以根据result.affectedRows方法进行判断

Web开发模式

基于服务器渲染的传统Web开发模式

  • 服务器发送给客户端的HTML页面,是在服务器通过字符串的拼接,动态生成的。因此,客户端不需要使用ajax这样的技术额外请求页面

优点:

  1. 前端耗时少。
  2. 有利于SEO

缺点:

  1. 占用服务器端资源
  2. 不利于前后端分离,开发效率低

基于前后端分离的新型Web开发模式
依赖于Ajax技术的广泛应用。前后端分离的Web开发模式,就是后端负责提供API接口,前端使用Ajax调试接口的开发模式
优点:

  1. 开发体验好
  2. 用户体验好
  3. 减轻服务器端的渲染压力

缺点:

  1. 不利于SEO

身份认证

通过一定的手段,完成对用户身份的确认

服务器渲染的身份认证方式-Session认证机制

HTTP协议的无状态性

HTTP协议的无状态性,指的是客户端的每次HTTP请求都是独立的,连续多个请求之间没有直接的关系,服务器不会主动保留每次HTTP请求的状态

Cookie

Cookie是储存在用户浏览器中的一段不超过4KB的字符串。它由一个名称,一个值和其他几个用来控制Cookie有效期,安全性,使用范围的可选属性组成

触发逻辑:

当客户端发起请求时,会把所有没过期的Cokkie一同发送给服务器。

特性

自动发送
域名独立
过期时限
4KB限制

不安全性

Cookie不具有安全性
由于Cookie是存储在浏览器中的,而且浏览器也提供了读写Cookie的API,因此Cookie很容易被伪造,不具有安全性。因此不建议服务器将用户的隐私数据,通过Cookie的形式发送给浏览器

Session的工作原理

在这里插入图片描述
express-session中间件

JWT

可以跨域请求
跨域认证解决方案

JWT的组成部分

JWT通常由三部分组成,分别是Header(头部),Payload(有效荷载),Signature(签名),

Header.Payload.Signature

JWT的相关包的安装

npm i jsonwebtoken express-jwt

jsonwebtoken 用来生成token 转化成JWT字符串
express-jwt JWT解析成JSON对象

Secret密钥

保证JWT字符串的安全性,防止JWT字符串在网络传输中被破解

JWT实例

const express = require('express')
const app = express();
// 导入JWT相关包
const token = require('jsonwebtoken')
const jwt = require('express-jwt')
// 跨域
const cors = require('cors')
app.use(cors())


// 获得页面发送过来的数据
app.use(express.urlencoded({extended: false}))
// 定义secret 密钥  字符串随便写,越复杂越好
const secret ='mynameyisizhaoyipeng no1 0.0'

// 注册将JWT字符串解析还原成JSON对象的中间件
// unless可以配置不需要接口权限的地址
// 更新以后的jWT 需要加入algorithms:['HS256'],设置JWT的算法
app.use(jwt({secret:secret,algorithms:['HS256']}).unless({path:[/^/api//]}))

// 全局中间件,铺货JSW失败的原因
app.use((err, req, res, next) => {
    // 这次错误是由 token 解析失败导致的
    if (err.name === 'UnauthorizedError') {
      return res.send({
        status: 401,
        message: '无效的token',
      })
    }
    res.send({
      status: 500,
      message: '未知的错误',
    })
  })

// post请求
app.post('/api/login',(req, res) => {
    // 将req.body请求体中的数据,转存为userinfo常量
    const userinfo = req.body
    if (userinfo.username !== 'admin' || userinfo.password !== '000000') {
        return res.send({
          status: 400,
          message: '登录失败!',
        })
      }
    // 利用jsonwebtoken 生成token
   const tokenStr =  token.sign({username:userinfo.username},secret,{expiresIn:'1s'})
    res.send({
        status:0,
        meg:"账号密码正确,允许登录",
        token:tokenStr,
    })
    
})
// 有权限的接口
app.get('/admin/getinfo',(req, res)=>{
    console.log(req.user)
    res.send({
        status:0,
        msg:'获取token成功',
        data:req.use

    })
})
// 启动服务器
app.listen(8888,function(){
    console.log('http://127.0.0.1:8888')
})

最后

以上就是风中黄蜂为你收集整理的node学习总结的全部内容,希望文章能够帮你解决node学习总结所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(61)

评论列表共有 0 条评论

立即
投稿
返回
顶部