千锋Node.js学习笔记

Posted 李英俊小朋友

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了千锋Node.js学习笔记相关的知识,希望对你有一定的参考价值。

千锋Node.js学习笔记

文章目录

写在前面

  • 封面 | 摘要 | 关键词

千锋Node.js学习笔记

Node.js
李英俊
前端
千锋
express
  • 学习链接:千锋HTML5前端开发教程1000集[P287: P427],共141集

  • 感想

    1. [20221008] node.js 这部分讲的真的很难顶,真想直接跳到vue。这个老师思想跳跃很大,讲课基于自己而不是基于受众。且不提我,很多老师体到的东西屏幕里的学生都很懵。前面说着说着就说到一些超纲知识点,说了又不详解,只会说后面会讲,会面会讲就不要体到前面,很多知识点之间跳跃性很大,缺乏逻辑性串讲。
    2. [20221010] 感觉node.js的主讲老师,很多常见的函数api都记不住,动不动就要查,跟着敲代码都要改来改去,脑阔痛。
    3. [20221017] 讲到cors的时候,老师本来想要直接复制代码,还说:“如果这段代码你没有看懂,说明前面的你没有认真听。” 我:???直接上PUA了可还行。
    4. [20221020] 讲fs.stat,这老师的基础真是一言难尽,如果不知道函数的使用和功能,你查也行啊,总不能蒙吧。。。
    5. [20221025] 讲express,中间件栈?明明是队列,自己编了个名字可还行,讲得乱七八糟、不知所云。我的评价是:稀烂。不就是路由匹配的问题嘛?加个next可以使得后面的路由继续被匹配到,这么简单的东西我一看就知道要说啥,真是服了。主动增加学习难度了这是。。。
    6. [20221116] 隔了一段时间了,中间学习的依然很痛苦。现在是学到了项目这一块,真的是想到哪儿写到哪儿。感觉就是做了一次项目就跑过来当老师了,啥也不懂啊这是,重构代码全靠蒙和试是吧。
    7. [20221121] 讲个项目,毫无章法,毫无逻辑,随时随地想重构就重构,想到哪儿说到哪儿,行就是赚到,不行就再找找,屏幕滚来滚去,啥都看不清楚,学尼玛。
    8. [20221215] 讲师的绝招:git add git commit 然后git check,合理。
  • 摘抄

    1. 父元素设置 position: relative;子元素设置 position: absolute; left: 50%; transform: translateX(-50%),可以实现内容的居中显示
    2. 激活当前元素,取消其他兄弟元素的激活:$(this).addClass('active').siblings().removeClass('active')
    3. 直接启动http服务器:npx http-server -p 9000
    4. 启动node.js服务器:nodemon cors.jsnode cors.js
  • 学习时遇到的问题

    1. CSS中的position:relative理解
    2. 『前端大白话』之 “flex:1”
    3. nvm-windows安装教程
    4. 查找第三方模块
    5. npm 全局安装与本地安装、开发依赖和生产依赖
    6. 箭头函数和function的区别
      • this的指向:使用function定义的函数,this的指向随着调用环境的变化而变化,而箭头函数中的this指向是固定不变的,一直指向定义函数的环境。
      • function是可以定义构造函数的,而箭头函数是不行的。
      • 由于js的内存机制,function的级别最高,而用箭头函数定义函数的时候,需要var(let const定义的时候更不必说)关键词,而var所定义的变量不能得到变量提升,故箭头函数一定要定义于调用之前!
      • 使用function声明函数时,可以使用arguments来获取传入函数的所有参数,而使用箭头函数声明的方法无法使用arguments来获取所有参数。
  • PS:相关工程代码都在 Github 上

1. 认识Node.js

  1. Node.js is a javascript runtime built on Chrome’s V8 JavaScript engine.

  2. 特性

    Node.js可以解析JS代码,没有浏览器安全级别的限制,提供很多系统级别的API

    • 文件的读写 File System

      const fs = require('fs')
      
      fs.writeFile('./log.text', 'hello', (err, data) => 
          if (err) 
      
          else
              console.log('文件创建成功');
          
      )
      

      运行上述代码:node index.js

    • 进程的管理 Process

      function main(argv)
          console.log(argv);
      
      
      main(process.argv)
      

      运行:node process.js 1 2

    • 网络通信 HTTP/HTTPS

      const http = require('http')
      
      const server = http.createServer((request, response) => 
          let url = request.url
          response.write(url)
          response.end()
      )
      
      server.listen(8090, 'localhost', ()=>
          console.log('localhost:8090');
      )
      
    • 。。。

  3. Node相关工具

    1. nvm:Node Version Manager
    2. npm:Node Package Manager
    3. nrm:npm registry manager
    4. npx:npm package extention

2. NVM

  • node.js的版本管理工具,windows不支持,需要安装其他的

    nvm-windows
    nodist
    
  • 查看软件版本:npm view node versions

  • 查看node版本:node -v

  • 查看已安装的node版本:nvm list

  • 切换node版本:nvm user 14.15.0

  • 设置默认版本:nvm alias default 14.15.0

3. NPM

  • 安装全局包:npm install jquery -g(--global)

  • 全局安装包的目录:C:\\Users\\用户\\AppData\\Roaming\\npm\\node_modules

  • 使用package.json可以实现本地包的安装:npm install xxx --save-dev

    • --save:可以替换为 -S
    • --save-dev:可以替换为 -D
    • 这里如果不加 -dev (开发环境),表示的是:将包安装在生产环境中,这样该包的信息会更新到 package.jsondependencies
    • 同理,开发环境的话,会把包的信息放到 devDependencies 键中
    • 最后使用 node i 来安装所有的依赖包
    • 查看特定名称的包:npm list | grep gulp
    • 安装 生产 环境下的包:npm i --production
    • 查看包有哪些版本:npm view jquery versions
    • 安装具体版本的包:npm i jquery@2.2.4
    • 安装某版本最高版本的包:npm i jquery@2
      • MAJOR:表示当前APR的主版本号,它的变化通常意味着APR的巨大的变化,比如体系结构的重新设计,API的重新设计等等,而且这种变化通常会导致APR版本的向前不兼容。
      • MINOR:称之为APR的次版本号,它通常只反映了一些较大的更改,比如APR的API的增加等等,但是这些更改并不影响与旧版本源代码和二进制代码之间的兼容性。
      • PATCH通常称之为补丁版本,通常情况下如果只是对APR函数的修改而不影响API接口的话都会导致PATCH的变化。 目前为止APR的最高版本是1.2.2,最早遵循这种规则的版本号是0.9.0,不过在0.9.0之前,APR还推出了两个版本a8和a9。
        • 如果为奇数:则是不稳定的patch
        • 所以一般某个major的最高版本为偶数patch
      • ^:该配置只锁定major版本号
      • ~:锁定major和minor版本号
      • :什么都不加是最严格的,指定版本号
      • *:最新版本
    • 清空npm缓存:npm cache clean --force
  • loadsh介绍(与underscore是竞品)

    • chunck:数组的分割
  • 自己发布包

    • 写一个函数 myChunk()

    • 暴露函数的接口:module.exports = myChunk

    • 调用:

      const myChunk = require('./index.js')
      console.log(myChunk([4, 5, 6, 7]));
      
    • 发布

      // npm登录
      npm adduser
      // 查看源
      npm config get registry
      // 切换淘宝源(样例,实际要切回官方的源)
      npm config set registry https://registry.npm.taobao.org
      // 切回官方源
      npm config set registry https://registry.npmjs.org
      // 发布
      npm publish
      // 查看当前项目引用了哪些包
      npm ls
      // 卸载包
      npm unpublish --force
      // 引用包
      var hello = require('pg19-npm')
      hello.sayHello()
      
  • package.json 描述文件

    • name:包名称
    • version:版本号
    • description:描述
    • main:暴露接口的主程序
    • scripts:执行时需要执行的脚本
    • respository:项目库(除了可以从npm官网安装,也可以通过github等安装)
    • keywords:关键词
    • author:作者
    • license:证数,一般为MIT
    • bugs:bug链接
    • homepage:主页地址
  • npm脚本

    • npm允许在package.json文件里面,使用scripts字段定义脚本命令

    • npm运行package.json中的脚本

      npm run runjs
      
    • 如果脚本中有多个,使用 &&& 连接

      • &:并行运行脚本
      • &&:串行运行脚本
    • 如果脚本名为 start 、 test 等特殊的名称时,可以省略 runnpm test

    • 获取package.json中的信息:

      console.log(process.env.npm_package_config_env)

      • 其中:congfig为第一级的key,env为二级key,取到的是config.env的值

      • 注意:如果直接获取的是config,是会报错的

      • 该方法只能通过配置package.json后运行里面的脚本才生效,如果直接运行对应的js会直接显示undefined

      • 在脚本内部也可以直接获取package.json的信息

        "scripts": 
        	"build": "echo $npm_package_config_env"
        
        
    • npm安装git上发布的包

      • npm install git+https://git@xxx
      • npm install git+ssh://git@xxx
  • cross-env

    • windows不支持 NODE_ENV=production 的设置方式

    • 解决:cross-env使得可以使用单个命令,而不必担心为平台正确设置或使用环境变量。这个迷你的包(cross-env)能够提供一个设置环境变量的scripts,让你能够以Unix方式设置环境变量,然后再Windows上也能兼容运行

    • 安装:npm install --save-dev cross-env

    • 可以直接在脚本中设置环境变量的值,比如说

      "scripts": 
      	"dev": "NODE_ENV=development gulp -f gulp.config.js",
      	"prod": "NODE_ENV=production gulp -f gulp.config.js"
      
      
    • 如果需要使用cross-env

      "scripts": 
      	"dev": "cross-env NODE_ENV=development gulp -f gulp.config.js",
      	"prod": "cross-env NODE_ENV=production gulp -f gulp.config.js"
      
      

4. NRM

  • npm的镜像源管理工具,有时候国外资源太慢,使用这个就可以快速地在npm源之间切换
  • 安装:npm install -g nrm
  • 查看可选的源:nrm ls
  • 切换nrm:nrm use taobao
  • 测试速度:nrm test

5. NPX

  • npm从5.2开始增加了npx命令,如果没有自带,可以手动安装:npm install -g npx
  • npx想要解决的主要问题,就是调用项目内部安装的模块
    • 需要使用某个库的时候,要么配置package.json后调用里面的脚本,或者进入到node_modules文件夹中找到对应的库,再运行
    • 比如:gulp -v 不行;但是 npx gulp -v 就可以了
    • 如果本地没有这个库,npx会自己下载,但不会在本地/全局安装。其实是安装在临时文件夹中,使用完后自动删除
  • npx --no-install http-server:让npx强制使用本地模块,不下载远程模块,本地不存在就会报错
  • npx --ignore-existing http-server:忽略本地的同名模块,强制安装使用远程模块

6. 模块/包与CommonJS

  1. 分类

    • 内置的模块
    • 第三方的模块
    • 自定义的模块
  2. 浏览器是没有require对象的

  3. 编写暴露的接口

    module.exports = 
    	name,
    	age
    
    
    • 可以通过这种方式,暴露多个接口

    • 也可以使用如下方式,其中exports是 module.exports 的引用

      exports.name = name
      exports.age = age
      

7. 常用内置模块

1. url

  • url.parse(urlString[, parseQueryString[, slashesDenoteHost]]):将链接解析为一连串的信息

    const url = require('url')
    const urlString = 'https://www.baidu.com:443/path/index.html?id=2#tag=3'
    
    logger.debug(url.parse(urlString));
    
    // 输出
    Url 
      protocol: 'https:',
      slashes: true,
      auth: null,
      host: 'www.baidu.com:443',
      port: '443',
      hostname: 'www.baidu.com',
      hash: '#tag=3',
      search: '?id=2',
      query: 'id=2',
      pathname: '/path/index.html',
      path: '/path/index.html?id=2',
      href: 'https://www.baidu.com:443/path/index.html?id=2#tag=3'
    
    
  • url.format(urlObject):将结构体的信息转为链接

    logger.debug(url.format(
        
            protocol: 'https:',
            slashes: true,
            auth: null,
            host: 'www.baidu.com:443',
            port: '443',
            hostname: 'www.baidu.com',
            hash: '#tag=3',
            search: '?id=2',
            query: 'id=2',
            pathname: '/path/index.html',
            path: '/path/index.html?id=2',
            href: 'https://www.baidu.com:443/path/index.html?id=2#tag=3'
        
    ))
    
    // 输出
    https://www.baidu.com:443/path/index.html?id=2#tag=3
    
  • url.resolve(from, to):实现路径的拼接,前向后向都可以

    logger.debug(url.resolve('http://www.abc.com/a', '/b'))
    logger.debug(url.resolve('http://www.abc.com/a', '../'))
    
    // 输出
    http://www.abc.com/b
    http://www.abc.com/
    
  • URLSearchParams:解析url之后得到数据体,然后获取对应的search(search: ‘?id=2’,

    const urlParams = new URLSearchParams(url.parse(urlString).search)
    logger.debug(urlParams);
    
    // 输出
    URLSearchParams  'id' => '2' 
    

2. querystring

  • querystring.parse(str[, sep[, eq[, options]]]):参数的解析,将url中的参数部分解析为数据体(对象)

    const querystring = require('querystring')
    var qs = 'x=3&y=4'
    var parsed = querystring.parse(qs)
    console.log(parsed)
    
    // 输出
    [Object: null prototype]  x: '3', y: '4' 
    
  • querystring.stringify(obj[, sep[, eq[, options]]]):将数据体中的参数和值解析为url的参数

    const querystring = require('querystring')
    var qo = 
      x: 3,
      y: 4
    
    var parsed = querystring.stringify(qo)
    console.log(parsed)
    
    // 输出
    x=3&y=4
    
  • querystring.escape(str):对url的参数进行编码

    const querystring = require('querystring')
    var str = 'id=3&city=北京&url=https://www.baidu.com'
    var escaped = querystring.escape(str)
    console.log(escaped)
    
    // 输出
    id%3D3%26city%3D%E5%8C%97%E4%BA%AC%26url%3Dhttps%3A%2F%2Fwww.baidu.com
    
  • querystring.unescape(str):解码

    const querystring = require('querystring')
    var str = 'id%3D3%26city%3D%E5%8C%97%E4%BA%AC%26url%3Dhttps%3A%2F%2Fwww.baidu.com'
    var unescaped = querystring.unescape(str)
    console.log(unescaped)
    
    // 输出
    id=3&city=北京&url=https://www.baidu.com
    

3. http

  • node的浏览端调试:node --inspect --inspect-brk server.js

  • node进程管理工具:一直监听,如果代码有修改会自动重启

    • supervisor
    • forever
    • nodemon
    • pm2
  • response.end()中也可以写返回的信息

  • get

    const http = require('http')
    const querystring = require('querystring')
    const https = require('https');
    
    const server = http.createServer((request, response) => 
        // console.log(response);
    
        // const url = request.url
        // console.log(url);
    
        https.get('https://www.xiaomiyoupin.com/mtop/mf/cat/list', (result) => 
            let data = ''
            result.on('data', (chunk) => 
                data += chunk
            )
            result.on('end', () => 
                response.writeHead(200, 
                    // 'content-type': 'text/html'
                    'content-type': 'application/json;charset=utf-8'
                )
                // response.write('<div>hello</div>')
                // response.write('"x": 1')
                // response.end('"x": 1')
                // console.log(data);
                // response.write(`"url": "$url"`)
                response.write(JSON.stringify(querystring.parse(data)))
                response.end()
            )
        )
    )
    
    server.listen(8080, () => 
        console.log('localhost:8080');
    )
    
  • post

    const http = require('http');
    const querystring = require('querystring');
    
    const postData = querystring.stringify(
        province: '上海',
        city: '上海',
        district: '宝山区',
        address: '同济啊吧啊吧',
        latitude: 43.0,
        longitude: 160.0,
        message: '求购一条小鱼',
        contact: '13666666666',
        type: 'sell',
        time: 1571217561
    )
    
    const options = 
        protocol: 'http:',
        hostname: 'localhost',
        method: 'post',
        port: 3000,
        path: '/data',
        headers: 
            'content-type': 'application/x-www-form-urlencoded',
            'Content-Length': Buffer.byteLength(postData),
        
    
    
    const server = http.createServer((req, res) => 
        const request = http.request(options, (result) => 
    
        )
        request.write(postData)
        request.end()
    
        res.end()
    )
    
    server.listen(8080, () => 
        console.log('localhost:8080');
    )
    

4. 跨域

  • jsonp利用 script 标签加载js不跨域的特性,从后端拉取js代码运行,jsonp中的p是padding(包裹数据的函数),拿到callback后,传入数据调用函数;cors就是在后台给前端返回一个首部字段:Access-Control-Allow-Origin;middleware:通过http-proxy-middleware实现地址的代理,从而实现了跨域。

jsonp

  • JSON with Padding,是 json 的一种"使用模式",可以让网页从别的域名(网站)那获取资料,即跨域读取数据。

  • 为什么我们从不同的域(网站)访问数据需要一个特殊的技术( JSONP )呢?这是因为 **同源策略 ** 。

  • 同源策略,它是由 Netscape 提出的一个著名的安全策略,现在所有支持 JavaScript 的浏览器都会使用这个策略。所谓同源是指,域名,协议,端口相同。

  • 当一个百度浏览器执行一个脚本的时候会检查这个脚本是属于哪个页面的 即检查是否同源,只有和百度同源的脚本才会被执行。

  • 核心<script> 标签的src属性并不被同源策略所约束,所以可以获取任何服务器上脚本并执行。

  • 案例:通过访问另一个服务器的api,并通过传参的方式把当前的函数传过去,实现了跨域 传参+调用函数

    • 当前html

      <!DOCTYPE html>
      <html lang="en">
      
      <head>
          <meta charset="UTF-8">
          <meta http-equiv="X-UA-Compatible" content="IE=edge">
          <meta name="viewport" content="width=device-width, initial-scale=1.0">
          <title>jsonp</title>
      </head>
      
      <body>
          <script>
              function getData(data) 
                  console.log(data);
              
          </script>
          <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.js"></script>
          <script src="http://localhost:8080/api/data?cb=getData"></script>
      </body>
      
      </html>
      
    • html中引用的跨域的Node.js

      const http = require('http')
      const url = require('url')
      
      const server = http.createServer((req, res) => 
          let urlstr = req.url
      
          // true 是为了解析 url中的query为一个字典
          let urlObj = url.parse(urlstr, true)
          switch(urlObj.pathname) 
              case '/api/data':
                  res.write(`$urlObj.query.cb("hello")`)
                  break
              default:
                  res.write('page not found.')
          以上是关于千锋Node.js学习笔记的主要内容,如果未能解决你的问题,请参考以下文章

      千锋Flask学习笔记

      千锋Flask学习笔记

      千锋Flask学习笔记

      weex开发学习笔记_环境搭建

      千锋Django学习笔记

      千锋Django学习笔记