node.js

目录

介绍

内置模块

fs

path

http

模块化

npm与包

第三方模块

express

数据库与身份认证


介绍

 Node.js一个基于 Chrome V8 引擎的 JavaScript 运行环境

浏览器中的JavaScript运行环境

node.js中的JavaScript运行环境

node.js仅仅提供了基础的功能和 API,但衍生出很多强大的工具和框架,有基于 Express 框架可以快速构建 Web 应用,基于 Electron 框架构建跨平台的桌面应用,基于 restify 框架快速构建 API 接口项目,还有读写和操作数据库、创建实用的命令行工具辅助前端开发…

内置模块

fs
fs 模块 是 Node.js 官方提供的、用来操作文件的模块。它提供了一系列的方法和属性,用来满足用户对文件的操作需求
const fs = require('fs')

fs.readFile('./files/1.txt', 'utf8', function(err, dataStr) {
  if (err) {
    return console.log('读取文件失败!' + err.message)
  }
  console.log('读取文件成功!' + dataStr)
})
const fs = require('fs')
fs.writeFile('./files/3.txt', 'ok123', function(err) {
  // 2.1 如果文件写入成功,则 err 的值等于 null
  // 2.2 如果文件写入失败,则 err 的值等于一个 错误对象
  // console.log(err)
  if (err) {
    return console.log('文件写入失败!' + err.message)
  }
  console.log('文件写入成功!')
})
path
path 模块 是 Node.js 官方提供的、用来 处理路径 的模块。它提供了一系列的方法和属性,用来满足用户对路径的处理需求
const path = require('path')
const fs = require('fs')
fs.readFile(path.join(__dirname, './files/1.txt'), 'utf8', function(err, dataStr) {
  if (err) {
    return console.log(err.message)
  }
  console.log(dataStr)
})
const path = require('path')
const fpath = '/a/b/c/index.html'

const fullName = path.basename(fpath)//index.html
const nameWithoutExt = path.basename(fpath, '.html')//index
const fext = path.extname(fpath)//.html
http
http 模块 是 Node.js 官方提供的、用来 创建 web 服务器 的模块。通过 http 模块提供的 http.createServer() 方法,就能方便的把一台普通的电脑,变成一台 Web 服务器,从而对外提供 Web 资源服务。
// 1. 导入 http 模块
const http = require('http')
// 2. 创建 web 服务器实例
const server = http.createServer()
// 3. 为服务器实例绑定 request 事件,监听客户端的请求
server.on('request', (req, res) => {
  // 定义一个字符串,包含中文的内容
  const str = `您请求的 URL 地址是 ${req.url},请求的 method 类型为 ${req.method}`
  // 调用 res.setHeader() 方法,设置 Content-Type 响应头,解决中文乱码的问题
  res.setHeader('Content-Type', 'text/html; charset=utf-8')
  // res.end() 将内容响应给客户端
  res.end(str)
})
// 4. 启动服务器
server.listen(80, () => {
  console.log('server running at http://127.0.0.1')
})
模块化
把代码进行模块化拆分的好处:
  • 提高了代码的复用性
  • 提高了代码的可维护性
  • 可以实现按需加载

node.js将模块分为了 3 大类,分别是:

  • 内置模块(内置模块是由 Node.js 官方提供的,例如 fs、path、http 等)
  • 自定义模块(用户创建的每个 .js 文件,都是自定义模块)
  • 第三方模块由第三方开发出来的模块,并非官方提供的内置模块,也不是用户创建的自定义模块,使用前需要先下载
const fs=require('fs')//加载内置模块
const custom=require('./custom.js')//加载自定义模块
const moment=require('moment')//加载第三方模块
//使用 require() 方法加载其它模块时,会执行被加载模块中的代码

函数作用域类似,在自定义模块中定义的变量方法等成员,只能在当前模块内被访问,这种模块级别的访问限制,叫做模块作用域;在每个 .js 自定义模块中都有一个 module 对象,它里面存储了和当前模块有关的信息,在自定义模块中,可以使用 module.exports 对象,将模块内的成员共享出去,供外界使用。外界用 require() 方法导入自定义模块时,得到的就是 module.exports 所指向的对象。

CommonJS 规定:
  • 每个模块内部,module 变量代表当前模块。
  • module 变量是一个对象,它的 exports 属性(即 module.exports是对外的接口
  • 加载某个模块,其实是加载该模块的 module.exports 属性。require() 方法用于加载模块
npm与包
Node.js 中的 第三方模块 又叫做 包。不同于 Node.js 中的内置模块与自定义模块, 包是由第三方个人或团队开发出来的,免费供所有人使用。Node.js 中的包都是免费且开源的,不需要付费即可免费下载使用。 包是基于内置模块封装出来的 ,提供了更高级、更方便的 API, 极大的提高了开发效率
npm, Inc. 公司 提供了一个地址为 https://registry.npmjs.org/ 的服务器,来对外共享所有的包,我们可以从这个服务器上下载自己所需要的包。 npm, Inc. 公司提供了一个包管理工具,我们可以使用这个包管理工具,从 https://registry.npmjs.org/ 服务器把需要的包下载到本地使用。这个包管理工具的名字叫做 Node Package Manager(简称 npm 包管理工具),这个包管理工具随着Node.js 的安装包一起被安装到了用户的电脑上。可以在终端中执行 npm -v 命令,来查看自己电脑上所安装的 npm 包管理工具的版本号, 如果想在项目中安装指定名称的包,需要运行如下的命令:
npm install 包的完整名称
如果想要快速创建 package.json 这个包管理配置文件, 需要运行如下的命令:
npm init -y

npm 规定,在 项目根目录 中, 必须 提供一个叫做 package.json 的包管理配置文件。用来记录与项目有关的一些配置信息。例如:
  • 项目的名称、版本号、描述等
  • 项目中都用到了哪些包
  • 哪些包只在开发期间会用到
  • 哪些包在开发部署时都需要用到
node_modules 文件夹 用来 存放所有已安装到项目中的包 。require() 导入第三方包时,就是从这个目录中查找并加载包。
package-lock.json 配置文件 用来 记录 node_modules 目录下的每一个包的下载信息, 运行 npm install 命令安装包的时候,npm 包管理工具会自动把 包的名称 版本号 ,记录到 package.json 中,直接运行 npm install 命令(或 npm i )则一次性安装所有的依赖包:

 

如果某些包 只在项目开发阶段 会用到,在 项目上线之后不会用到 ,则建议把这些包记录到 devDependencies 节点中。如果某些包在 开发 项目上线之后 都需要用到,则建议把这些包记录到 dependencies 节点中。

切换npm包下载的镜像源

 

 

第三方模块

express
Express 是 基于 Node.js 平台 快速、开放、极简 Web 开发框架 。通俗的理解:Express 的作用和 Node.js 内置的 http 模块类似, 是专门用来创建 Web 服务器的
Express 的本质 :就是一个 npm 上的第三方包,提供了快速创建 Web 服务器的便捷方法
// 1. 导入 express
const express = require('express')
// 2. 创建 web 服务器
const app = express()

// 4. 监听客户端的 GET 和 POST 请求,并向客户端响应具体的内容
app.get('/user', (req, res) => {
  // 调用 express 提供的 res.send() 方法,向客户端响应一个 JSON 对象
  res.send({ name: 'zs', age: 20, gender: '男' })
  // 通过 req.query 可以获取到客户端发送过来的 查询参数
  console.log(req.query)
})
app.post('/user', (req, res) => {
  // 调用 express 提供的 res.send() 方法,向客户端响应一个 文本字符串
  res.send('请求成功')
})
// 在这里,调用 express.static() 方法,快速的对外提供静态资源
app.use('/files', express.static('./files'))
// 3. 启动 web 服务器
app.listen(80, () => {
  console.log('express server running at http://127.0.0.1')
})

在 Express 中,路由指的是客户端的请求服务器处理函数之间的映射关系。Express 中的路由分 3 部分组成,分别是请求的类型请求的 URL 地址处理函数,每当一个请求到达服务器之后,需要先经过路由的匹配,只有匹配成功之后,才会调用对应的处理函数。在匹配时,会按照路由的顺序进行匹配,如果请求类型请求的 URL 同时匹配成功,则 Express 会将这次请求,转交给对应的 function 函数进行处理

 express推荐将路由抽离为单独的模块。步骤如下:

  • 创建路由模块对应的 .js 文件
    // 这是路由模块
    // 1. 导入 express
    const express = require('express')
    // 2. 创建路由对象
    const router = express.Router()
    
    // 3. 挂载具体的路由
    router.get('/user/list', (req, res) => {
      res.send('Get user list.')
    })
    router.post('/user/add', (req, res) => {
      res.send('Add new user.')
    })
    
    // 4. 向外导出路由对象
    module.exports = router

  • 调用 express.Router() 函数创建路由对象
  • 向路由对象上挂载具体的路由
  • 使用 module.exports 向外共享路由对象
  • 使用 app.use() 函数注册路由模块
    const express = require('express')
    const app = express()
    // 1. 导入路由模块
    const router = require('./03.router')
    // 2. 注册路由模块
    app.use('/api', router)
    
    // 注意: app.use() 函数的作用,就是来注册全局中间件
    app.listen(80, () => {
      console.log('http://127.0.0.1')
    })
    
    客户端发起的 任何请求 ,到达服务器之后, 都会触发的中间件 ,叫做全局生效的中间件。
    通过调用 app.use( 中间件函数 ) ,即可定义一个 全局生效 的中间件;多个中间件之间, 共享同一份 req res。基于这样的特性,我们可以在 上游的中间件中, 统一为 req 或 res 对象添
    自定义 属性 方法 ,供 下游 的中间件或路由进行使用
    const express = require('express')
    const app = express()
    
    // 定义一个最简单的中间件函数
     const mw = function (req, res, next) {
       console.log('这是最简单的中间件函数')
       // 把流转关系,转交给下一个中间件或路由
       next()
     }
    //全局生效的中间件
    app.use(mw)
    定义多个 全局中间件:客户端请求到达服务器之后,会按照中间件 定义的先后顺序依次进行
    调用,示例代码如下:
    // 定义第一个全局中间件
    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.')
    })

    定义多个局部中间件

    
    // 1. 定义中间件函数
    const mw1 = (req, res, next) => {
      console.log('调用了第一个局部生效的中间件')
      next()
    }
    
    const mw2 = (req, res, next) => {
      console.log('调用了第二个局部生效的中间件')
      next()
    }
    
    // 2. 创建路由
    app.get('/', [mw1, mw2], (req, res) => {
      res.send('Home page.')
    })

    中间件注意事项

    • 一定要在路由之前注册中间件
    • 客户端发送过来的请求,可以连续调用多个中间件进行处理
    • 执行完中间件的业务代码之后,不要忘记调用 next() 函数
    • 为了防止代码逻辑混乱,调用 next() 函数后不要再写额外的代码
    • 连续调用多个中间件时,多个中间件之间,共享 req 和 res 对象

 

通过 app.use() app.get() app.post() 绑定到 app 实例上的中间件,叫做应用级别的中间件:

//应用级别的中间件(全局中间件)
app.use((req, res, next) => {
    next()
})
//应用级别的中间件(局部中间件)
app.get('/', mw1, (req, res) => {
  res.send('Home page.')
})

 

绑定到 express.Router() 实例上的中间件,叫做路由级别的中间件。它的用法和应用级别中间件没有任何区别。只不过, 应用级别中间件是绑定到 app 实例上 路由级别中间件绑定到 router 实例上
const express = require('express')
const router = express.Router()
//路由级别中间件
router.use(function(req, res,next) => {
  next()
})
app.use('/',router)
错误级别中间件的 作用 :专门用来捕获整个项目中发生的异常错误,从而防止项目异常崩溃的问题。错误级别的中间件, 必须注册在所有路由之后
格式 :错误级别中间件的 function 处理函数中, 必须有 4 个形参 ,形参顺序从前到后,分别是 ( err , req, res, next)。
// 1. 定义路由
app.get('/', (req, res) => {
  // 1.1 人为的制造错误
  throw new Error('服务器内部发生了错误!')
  res.send('Home page.')
})

// 2. 定义错误级别的中间件,捕获整个项目的异常错误,从而防止程序的崩溃
app.use((err, req, res, next) => {
  console.log('发生了错误!' + err.message)
  res.send('Error:' + err.message)
})
自 Express 4.16.0 版本开始,Express 内置了 3 个 常用的中间件,极大的提高了 Express 项目的开发效率和体验:
  • express.static 快速托管静态资源的内置中间件,例如: HTML 文件、图片、CSS 样式等(无兼容性)
  • express.json 解析 JSON 格式的请求体数据(有兼容性,仅在 4.16.0+ 版本中可用)
  • express.urlencoded 解析 URL-encoded 格式的请求体数据(有兼容性,仅在 4.16.0+ 版本中可用)
    // 注意:除了错误级别的中间件,其他的中间件,必须在路由之前进行配置
    // 通过 express.json() 这个中间件,解析表单中的 JSON 格式的数据
    app.use(express.json())
    // 通过 express.urlencoded() 这个中间件,来解析 表单中的 url-encoded 格式的数据
    app.use(express.urlencoded({ extended: false }))
    非 Express 官方内置的,而是由第三方开发出来的中间件,叫做第三方中间件。在项目中,大家可以 按需下载 配置 第三方中间件,从而提高项目的开发效率。 例如:在 express@4.16.0 之前的版本中,经常使用 body-parser 这个第三方中间件,来解析请求体数据
    
    // 1. 导入解析表单数据的中间件 body-parser
    const parser = require('body-parser')
    // 2. 使用 app.use() 注册中间件
    app.use(parser.urlencoded({ extended: false }))
    // app.use(express.urlencoded({ extended: false }))
    
    app.post('/user', (req, res) => {
      // 如果没有配置任何解析表单数据的中间件,则 req.body 默认等于 undefined
      console.log(req.body)
      res.send('ok')
    })
    数据库与身份认证
    mysql 模块是托管于 npm 上的 第三方模块 。它提供了在 Node.js 项目中 连接 操作 MySQL 数据库的能力。想要在项目中使用它,需要先运行如下命令,将 mysql 安装为项目的依赖包
    npm install mysql
    // 1. 导入 mysql 模块
    const mysql = require('mysql')
    // 2. 建立与 MySQL 数据库的连接关系
    const db = mysql.createPool({
      host: '127.0.0.1', // 数据库的 IP 地址
      user: 'root', // 登录数据库的账号
      password: '123456', // 登录数据库的密码
      database: 'cloud_user', // 指定要操作哪个数据库
    })
    // 向 users 表中,新增一条数据,其中 username 的值为 Spider-Man,password 的值为 pcc123
    const user = { username: 'Spider-Man', password: 'pcc123' }
    const sqlStr = 'insert into users set ?'
    db.query(sqlStr, user, (err, results) => {
      if (err) return console.log(err.message)
      if (results.affectedRows === 1) {
        console.log('插入数据成功!')
      }
    }) 
    在 Express 项目中,只需要安装 express-session 中间件,即可在项目中使用 Session 认证
    // 导入Session 中间件
    var session = require('express-session')
    app.use(
      session({
        secret: 'itheima',
        resave: false,
        saveUninitialized: true,
      })
    )
    
    app.post('/api/login', (req, res) => {
      if (req.body.username !== 'admin' || req.body.password !== '000000') {
        return res.send({ status: 1, msg: '登录失败' })
      }
    
      // 请将登录成功后的用户信息,保存到 Session 中
      req.session.user = req.body // 用户的信息
      req.session.islogin = true // 用户的登录状态
      res.send({ status: 0, msg: '登录成功' })
    })
    app.get('/api/username', (req, res) => {
      // 请从 Session 中获取用户的名称,响应给客户端
      if (!req.session.islogin) {
        return res.send({ status: 1, msg: 'fail' })
      }
      res.send({
        status: 0,
        msg: 'success',
        username: req.session.user.username,
      })
    })
    JWT(英文全称:JSON Web Token)是目前 最流行 跨域认证解决方案
    JWT 通常由三部分组成,分别是 Header (头部)、 Payload (有效荷载)、 Signature (签名)。三者之间使用英文的“.”分隔。
    客户端收到服务器返回的 JWT 之后,通常会将它储存在 localStorage sessionStorage 中。此后,客户端每次与服务器通信,都要带上这个 JWT 的字符串,从而进行身份认证。推荐的做法是 把 JWT 放在 HTTP 请求头的 Authorization 字段中 ,格式如下:
    Authorization: Bearer <token>

     

 

// TODO_01:安装并导入 JWT 相关的两个包,分别是 jsonwebtoken 和 express-jwt
const jwt = require('jsonwebtoken')
const expressJWT = require('express-jwt')
// TODO_02:定义 secret 密钥,建议将密钥命名为 secretKey
const secretKey = 'itheima No1 ^_^'
app.post('/api/login', function (req, res) {
  // 将 req.body 请求体中的数据,转存为 userinfo 常量
  const userinfo = req.body
  // 登录失败
.....
  // 登录成功
  // TODO_03:在登录成功之后,调用 jwt.sign() 方法生成 JWT 字符串。并通过 token 属性发送给客户端
  const tokenStr = jwt.sign({ username: userinfo.username }, secretKey, { expiresIn: '30s' })
  res.send({
    status: 200,
    message: '登录成功!',
    token: tokenStr, // 要发送给客户端的 token 字符串
  })
})

// TODO_04:注册将 JWT 字符串解析还原成 JSON 对象的中间件
// 注意:只要配置成功了 express-jwt 这个中间件,就可以把解析出来的用户信息,挂载到 req.user 属性上
app.use(expressJWT({ secret: secretKey }).unless({ path: [/^\/api\//] }))

// 这是一个有权限的 API 接口
app.get('/admin/getinfo', function (req, res) {
  // TODO_05:使用 req.user 获取用户信息,并使用 data 属性将用户信息发送给客户端
  res.send({
    status: 200,
    message: '获取用户信息成功!',
    data: req.user, // 要发送给客户端的用户信息
  })
})

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值