Nodejs深入浅出

236 阅读7分钟

我们可以创建一个 nodejs 的项目

mkdir later
cd later
npm init -y

通过 npm init 可以让我快速 初始化 package.json,它会让我们确认各种东西,所以如果想快速初始化可以 通过 npm init -y 这个指令 当然 我们可以通过 最简单的 npm install 去安装依赖, --save 可以让它保存在package.json中, 然后输出一棵 ** node_modules ** 树 ,理应来说它 npm install 应该是一个 ** 纯函数**

  1. 不同版本npm的安装算法不同
  2. 某些依赖自上次安装以来,可能已经发布了新的版本,因此将根据package.json中的semverrang version去更新依赖

比如

npm install --save express 

当我们想卸载该依赖的时候我们可以

npm rm express --save

这个时候我们发现 会在该文件下的目录下面,有一个 package-lock.json 文件,字面上理解 是锁定版本的意思。
我们再来谈一下这个** package-lock.json ** 文件

module模块概念

  1. 每个.js文件即是一个模块。当我们 console.log(module)的时候
Module {
  id: '.',
  path: 'D:\\code\\AICode20200624\\Engine\\src',
  exports: { a: 1 },
  parent: null,
  filename: 'D:\\code\\AICode20200624\\Engine\\src\\index.js',
  loaded: false,
  children: [],
  paths: [
    'D:\\code\\AICode20200624\\Engine\\src\\node_modules',
    'D:\\code\\AICode20200624\\Engine\\node_modules',
    'D:\\code\\AICode20200624\\node_modules',
    'D:\\code\\node_modules',
    'D:\\node_modules'
  ]
}

会输出如上所示的数据格式,其中 拥有 exports 属性

  1. exports 和 module.exports的关系
module.exports 对象是由模块系统创建的。
module.exports = {
    a: 1
}
exports.a = 1

以上的使用方式是等效的,如果 exports.b = 2 ,那么输出的export则是以下内容

Module {
  id: '.',
  path: 'D:\\code\\AICode20200624\\Engine\\src',
  exports: { b: 2, a: 1 },
  parent: null,
  filename: 'D:\\code\\AICode20200624\\Engine\\src\\index.js',
  loaded: false,
  children: [],
  paths: [
    'D:\\code\\AICode20200624\\Engine\\src\\node_modules',
    'D:\\code\\AICode20200624\\Engine\\node_modules',
    'D:\\code\\AICode20200624\\node_modules',
    'D:\\code\\node_modules',
    'D:\\node_modules'
  ]
}

Express

Express是以Node自带的http模块为基础,致力于在HTTP请求和响应上来建模Web程序

中间件

中间件的本质其实是一个函数,在接收到和返回的过程中进行处理。

let Koa = require('koa');
let app = new Koa();
app.use(async (ctx,next)=>{
    console.log(1);
   await next();
    console.log(2);
});
app.use(async (ctx,next)=>{
    console.log(3);
   await next();
    console.log(4);
});
app.listen("3000"); 

先来看看这段代码输出是的 1324 ,它的执行过程很像一颗洋葱,以 next 作为分界,先执行next之前的内容

本地变量 和 模块变量之间的关系

前文:笔者在本地 a.js 新建了一个变量a=1.1在b.js 新建了一个变量a=2 导出了一个module.exports={a},在主模块index.js引用了之后发现a被赋值为2

这个时候是因为模块间相互调用导致的,在模块间相互只用之前,a会导出一个export供另外一个使用,直到另一个完全执行完了,才会export b给a

通过Path.resolve API聊一聊nodejs中路径的问题

如果没有以'./','../'和'/'开头的文件,在CommonJS里面,寻找依赖模块是 比如a/b/c.js 其中c.js引用了d.js,那么模块的查找顺序为a/b/node_moudles/d,如果再找不到则会去调用a/node_modules/d,最后会在全局目录加载 如果是目录模块,在 package.json 文件中,会指定一个main入口.如果一个都找不到则会报错 can't find module xxxx

Content-type的类型

POST请求的消息主体放在entity body中,服务端根据请求头中的Content-Type字段来获取消息主体的编码方式,进而进行解析数据。 一、application/x-www-form-urlencoded
最常见的 POST 提交数据的方式,原生Form表单,如果不设置 enctype 属性,默认为application/x-www-form-urlencoded 方式提交数据。
首先,Content-Type被指定为 application/x-www-form-urlencoded;其次,提交的表单数据会转换为键值对并按照 key1=val1&key2=val2 的方式进行编码,key 和 val 都进行了 URL 转码。大部分服务端语言都对这种方式有很好的支持。
另外,如利用AJAX 提交数据时,也可使用这种方式。例如 jQuery,Content-Type 默认值都是”application/x-www-form-urlencoded;charset=utf-8”。
二、multipart/form-data
另一个常见的 POST 数据提交的方式, Form 表单的 enctype 设置为multipart/form-data,它会将表单的数据处理为一条消息,以标签为单元,用分隔符(这就是boundary的作用)分开,类似我们上面Content-Type中的例子。
由于这种方式将数据有很多部分,它既可以上传键值对,也可以上传文件,甚至多个文件。当上传的字段是文件时,会有Content-Type来说明文件类型;Content-disposition,用来说明字段的一些信息。每部分都是以 –boundary 开始,紧接着是内容描述信息,然后是回车,最后是字段具体内容(字段、文本或二进制等)。如果传输的是文件,还要包含文件名和文件类型信息。消息主体最后以 –boundary– 标示结束。
三、application/json
Content-Type: application/json 作为响应头比较常见。实际上,现在越来越多的人把它作为请求头,用来告诉服务端消息主体是序列化后的 JSON 字符串,其中一个好处就是JSON 格式支持比键值对复杂得多的结构化数据。由于 JSON 规范的流行,除了低版本 IE 之外的各大浏览器都原生支持JSON.stringify,服务端语言也都有处理 JSON 的函数,使用起来没有困难。 Google 的 AngularJS 中的 Ajax 功能,默认就是提交 JSON 字符串。
四、text/xml
XML的作用不言而喻,用于传输和存储数据,它非常适合万维网传输,提供统一的方法来描述和交换独立于应用程序或供应商的结构化数据,在JSON出现之前是业界一大标准(当然现在也是),相比JSON的优缺点大家有兴趣可以上网search。因此,在POST提交数据时,xml类型也是不可缺少的一种,虽然一般场景上使用JSON可能更轻巧、灵活。
五、binary (application/octet-stream)
在Chrome浏览器的Postman工具中,还可以看到”binary“这一类型,指的就是一些二进制文件类型。如application/pdf,指定了特定二进制文件的MIME类型。就像对于text文件类型若没有特定的子类型(subtype),就使用 text/plain。类似的,二进制文件没有特定或已知的 subtype,即使用 application/octet-stream,这是应用程序文件的默认值,一般很少直接使用 。
对于application/octet-stream,只能提交二进制,而且只能提交一个二进制,如果提交文件的话,只能提交一个文件,后台接收参数只能有一个,而且只能是流(或者字节数组)。 很多web服务器使用默认的 application/octet-stream 来发送未知类型。出于一些安全原因,对于这些资源浏览器不允许设置一些自定义默认操作,导致用户必须存储到本地以使用。一般来说,设置正确的MIME类型很重要。

其中参数对象需要JSON.stringify.

nodejs高并发控制

Q: 如何控制高并发 如果有50个api 但是一次性只能7个api
A: nodejs高并发大流量的设计实现,控制并发的三种方法 eventproxy、async.mapLimit、async.queue控制并发

crypto 模块

  1. RSA算法

RSA算法是1977年由Ron Rivest、Adi Shamir和Leonard Adleman共同提出的,所以以他们三人的姓氏的头字母命名。

RSA是一种非对称加密的算法,是一个公钥和一个私钥组成的密钥对,可以通过

  • 公钥加密,私钥解密
  • 私钥加密, 公钥解密

公钥可以暴露的但是私钥是一定是私有的。

dependencies 和 devDependencies 的区别


npm install *** --save
npm install ***  --save-dev
//–save会把依赖包名称添加到package.json文件dependencies键下,–save-dev则添加到package.json文件devDependencies键下
链接:https://juejin.cn/post/6844903794086510600

devDependencies 里面的插件只用于开发环境,不用于生产环境。 dependencies 是需要发布到生产环境的。