③ nodejs

NodeJS

1 模块化

1.1 框架

框架 规范 区别 定义与引入
require.js AMD 前端+异步 define + require()
sea.js CMD 前端+异步
nodejs CommonJS 后端+同步 module.exports + require()
ECMAScript2015 ESModule 前端+同步
    let jq = require(['jquery'], _ => {});
    console.log(jq);//undefined
    let http = require('http');
    console.log(http);

1.2 CommonJS规范模块分类

1.2.1 内置模块:NodeJS内部模块

  • 引入方式:require(模块名))

1.2.2 自定义模块

  • 定义:module.exports
  • 引用:require(相对路径)

1.2.3 第三方模块

  • 安装npm

1.2.4 文件模块

  • 一般指json文件

2 客户端与服务器

  • 前端JS = ECMAScript+BOM+DOM

  • 后端JS = ECMAScript+I/O

2.1 一个请求的细节

  • 请求request

  • 响应response

    • Content-Type

2.2 静态资源服务器

  • http 创建一个服务器

  • url 处理请求地址

  • path 处理文件地址

  • fs 文件处理

2.2.1 http

http/https 短连接(请求服务器并返回后,与服务器就断开连接)
webSocket 长连接(与服务器连接后不会断开)
长连接
  • 服务器主动

  • 无跨域限制

  • 在不支持webSocket的浏览器上如何实现

    • 轮询:定时器(嵌套setTimeout
  setTimeout(function show() {
    console.log(666)
    setTimeout(show, 5000)
  }, 5000)

2.2.2 文件的操作: fs模块

  • fs.readFile()/fs.readFileSync()

  • fs.writeFile()/fs.writeFileSync()

  • fs.appendFile()/fs.appendFileSync()

  • 全局变量

    • __dirname 当前文件所在的目录地址

    • __filename 当前文件所在地址

大文件的读取与写入:分多次完成文件的读写操作
  • stream文件流:文件的液体状态

  • 读取流(以流的方式读取文件内容)

    • fs.createReadStream(filepath)
  • 写入流

  • 管道流

    gulp.task('compileSass',()=>{
        gulp.src('./src/sass/home.scss')   //返回一个读取流
        .pipe(sass())
        .pipe(rename())
        .pipe(gulp.dist('./dist')) // gulp.dist()返回一个写入流
    })

3 第三方模块

3.1 安装:npm

  • 全局安装:为了在命令行使用

  • 项目安装:为了在代码中引用require

3.2 express

3.2.1 中间件Middleware

定义
  • 在到达目的前进行操作
使用
  • app.use(middleware)
分类
  • 内置中间

    • express.static()

    • express.json()

    • express.urlencoded()

    • express.Router()

  • 自定义中间

    中间件是一个函数,格式为 function(request, response, next){}

    • request 请求对象,保存客户端信息

    • response 响应对象,保存服务端信息

    • next() 是否进入下一个中间件的方法

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

4 接口编写(路由编写)

利用模块化思想实现接口与路由的编写

4.1 接口地址

  • 商品
  • 注册
  • 登录

4.2 RESTful规范接口

4.2.1 根据请求类型不同定义不同的接口

  • get

  • post

  • patch/put

  • delete

4.2.2 根据不同的地址实现不同的接口

  • get /goods 所有商品

  • post /goods 增加商品

  • get /goods/:id 单个商品

  • delete /goods/:id 删除商品

  • patch/put /goods/:id 修改商品(patch部分修改,put完全修改)

4.3 接口测试工具

  • postman

4.4 接收参数

  • 动态路由:request.params

  • url参数(?后面的参数):req.query

  • 请求体参数(post,patch):req.body

必须借助第三方中间件来获取

5 路由模块化

  • CommonJS:利用commonJS规范把路由分离到单独的文件中

  • 中间件express.Router():利用中间件把所有模块组合成一个完成的应用

6 Promise对象

6.1 状态

  • Pending 初始状态

  • Resolved 成功状态

  • Rejected 失败状态

状态只能从Pending改成Resolved或从Pending改成Rejected

6.2 应用场景

  • 解决回调地狱

  • 方法的封装

6.3 ES7的async & await

让我们以同步的代码实现异步编程

  • await 用于等待Promise对象的返回结果

    await不能单独使用,必须放在async函数中

  • async 是函数定义的关键字,利用async定义的函数会返回一个Promise对象

    async函数中的返回值,就是promise状态为Resolved时的值

    function getData(url,callback) {
        let data;
        let xhr = new XMLHttpRequest();
        xhr.onload = () => {
            data = xhr.responseText;
            callback(data)
        }
        xhr.open('get',url,true);
        xhr.send();
        return data;
    }

    let data = getData('/goods/123');
    console.log(data);//undefined

    // 利用回调函数来获取异步请求的数据
    getData('/goods/10086', function(data) {
        console.log(data)
    });


    // 利用Promise改造
    function getData(url){
        return new Promise((resolve,reject) => {
            let data;
            let xhr = new XMLHttpRequest();
            xhr.onload = () => {
                data = xhr.responseText;
                resolve(data)
            }
            xhr.open('get',url,true);
            xhr.send();
        })
    }

    getData('/goods/10086').then(data => {
        console.log(data)
    })

    (async function() {
       let data = await getData('/goods/10086')
    })();

7 跨域解决方案

7.1 为什么会存在跨域: 安全性问题(一切的根源:js是一门客户端语言)

7.2 解决方案

7.2.1 jsonp -- json with padding

  • 步骤

    1. 创建全局函数

    2. 利用script标签发起请求,并发送全局函数名

    3. 后端接收全局函数名,并返回函数执行的js代码,顺便出入数据

  • 缺点

    • 只能get请求

    • 不是一个ajax请求

7.2.2 CORS -- Cross Origin Resource Sharing

  • 一个真正的ajax跨域请求方案

  • 操作步骤

    1. 设置响应头
    • Access-Control-Allow-Origin

    • Access-Control-Allow-Headers

    • Access-Control-Allow-Methods

    1. 处理复杂跨域中的OPTIONS请求

7.2.3 服务器代理

  • 目标服务器有接口:代理 http-proxy-middleware

  • 目标服务器没有接口:爬 request & cheerio

    • 会分析html结构

    • 会使用工具

8 页面渲染方式

8.1 客户端渲染(BSR):前后端分离

8.1.1 后端:编写数据接口

8.1.2 前端:发起ajax请求,拿到数据后,遍历生成html结构

8.1.3 优点

  • 与用户的交互感更强

  • 用户体验更好

  • 开发更灵活

8.1.4 请求过程

  1. 输入地址,返回index.html

  2. 解析html,返现script

  3. 请求服务器,返回js代码

  4. 发起ajax请求,返回数据

  5. 解析数据,生成html结构

8.2 服务端渲染(SSR):前后端不分离

8.2.1 后端:生成html结构并响应到前端

8.2.2 优点

  • SEO

  • 速度更快

8.2.3 请求过程

  1. 输入地址,返回index.html

  2. 由于所有的html结构已经在服务器生成完毕,浏览器解析html结构

9 数据库

  • MySQL:关系型数据库,类似与表格

  • MongoDB:非关系型数据库,类似于json

数据库 数据记录
MySQL database table row
MongoDB database collection document

9.1 在NodeJS中使用MongoDB

  • 驱动(第三方模块)

    • mongodb

    • mongoose

  • 统一返回前端的数据格式

10 面试题

  • async & await

  • 前后端的理解

    • 前端 FE
    • 后端 BE
    • 沟通
  • RESTful规范的理解

    • 请求类型
    • 请求路径
  • 怎么理解Express中间件

    • 内置
    • 自定义
    • 第三方
上一篇:浏览器内置对象/事件/ajax


下一篇:2021-07-12