Vinson

Vinson

Nodejs

发表于 2023-09-01
Vinson
阅读量 24

node.js 模块引入

require 引入模块-commonjs规范

核心模块

require('http');// 引入 http 模块
js
  • 引入的模块会先从当前目录 node_modules 找,没有继续往上一级目录找,直到根目录,没有则报错
  • 文件模块:一个模块就是一个js文件
  • 引入的是路径必须以 ./ 或 …/ 开头
  • 引入后返回一个对象,返回的就是引入模块的返回值
var md = require('./02-module.js');// 引入本地模块 .js可以省略
js

每一个 js 文件模块都有一个文件作用域,无法返回引入模块的变量

exports 暴露给外部的变量

exports.变量名 = '';// 另一个文件即可访问该变量
js

引入自定义模块

  1. node_modules 下文件夹名字为模块名字, require 引入文件夹名字
  2. nodejs会自动找到文件夹下的 index.js 文件。如果不是 index 会报错
  3. 修改模块文件夹下 package.json 的 main 参数可以设置引入时的 index 为其他名字

模块的参数

console.log(arguments.callee + ''); // 当前函数 + '' 隐式调用 toString
  // 函数最开始添加此代码
function (exports, require, module, __filename, __dirname) {
  console.log(arguments.callee + '');
  // 函数结尾添加此代码
}
js

实际上模块中运行的代码都包装在一个函数中,并在执行时传递5个实参

  • require:函数,用来引入外部的模块
  • exports:将对象或变量暴露到外部
  • module
    • module 代表这个函数的本身
    • exports 就是 module 的属性
    • 既可以使用 module.exports 导出,也可以使用 exports 导出
module.exports == exports;// true
js
  • __filename:
    e:\Web\Node\createHttp.js
    ​ 当前文件所在路径

  • __dirname:
    ​e:\Web\Node
    ​ 当前文件夹所在路径

exports
exports是module.exports的引用,module.exports是真实存在的,最终返回的是module.exports

// 可以用
exports.name = 'xx';

// 不可用
exports = { /* 代码 */ } 
// 赋值对象会改变引用地址,实际的 module.exports 对象内的值并没有被修改

// 可用
module.exports.name = 'xx';

// 可用
module.exports = {/* 代码 */}

module = { exports: {} };
exports = module.exports;

exports.age = 22;
console.log(exports, module.exports);

module.exports = {};
console.log(exports, module.exports);
js

package.json

dependencies:{} 依赖,此包依赖另外的哪些包 类型jq插件依赖jq
description: '' 描述
devDependencis: {} 开发环境依赖,生成环境不依赖
homepage: 'http...' 主页
license: '' 权限
main: ''主文件
maintainers: {} 主要贡献者
contributors: 维护者
bugs: 提交bug地址
name: '' 包的名字
version: 版本
keywords: 关键字
repositories: 仓库
os: 系统
"scripts": {
  "start": "node ./bin/www", // 用 npm start 启动www.js 只有键为start可以省略 run
  "dev":"nodemon ./bin/www" // 用npm run dev 启动 www.js 
}
js

dos 小黑窗与 npm 指令

dos 小黑窗指令

  • dir:显示当前目录中的内容
  • cd:切换目录
  • 盘符冒号:切换盘符
  • cls:清屏
  • mkdir:创建目录
  • rmdir:删除目录
  • . 代表当前目录
  • … 代表上级目录

npm 指令

  • npm -v:查看版本
  • npm -version:查看npm模块所有版本
  • npm:帮助说明
  • npm search 包名:搜索模块
  • npm install 包名:在当前目录安装模块
    • 简写 npm i 包名
  • npm install 包名 -g:在全局模式安装包
  • npm install 包名 --save:安装包并添加到依赖中 cnpm必须要加—save
  • npm install 包名 -S:安装包并添加到依赖中
  • npm install :下载package依赖的包
  • npm remove 包名:删除一个模块
    • 简写 npm r 包名
  • npm uninstall 包名:删除
  • npm install 文件路径:本地安装一个路径
  • npm install 包名 --registry=地址:从镜像源安装
  • npm update 包名:更新某个包的版本
  • npm config set registry 地址:设置镜像源

将npm服务器切到国内淘宝服务器(镜像服务器),在dos小黑窗中分别执行下面的命令:

npm config set registry https://registry.npm.taobao.org --global
npm config set disturl https://npm.taobao.org/dist --global
js
  • npm init --yes:当前目录强制生成package.json
  • npm init [-y]:自动生成 packge.json:
"scripts": {
  "start": "node ./bin/www", // 用 npm start 启动 www.js 只有键为 start 可以省略 run
  "dev":"nodemon ./bin/www" // 用 npm run dev 启动 www.js 
}
js

Node.js Buffer 缓冲区

// 创建一个 10 字节的 buffer,长度一旦确定不能更改
var buf = Buffer.alloc(10);

// 转成 16 进制存入
buf[0] = 88;// <Buffer 58 00 00 00 00 00 00 00 00 00>
buf[1] = 0xaa; // <Buffer 58 aa 00 00 00 00 00 00 00 00>
buf[10] = 11;// 没有第十位 设置没效果
buf[3] = 256; // 00 
/* 最大 255,255 转 16 进制是 ff; 256 二进制 1 后面八个 0,存的时候取二进制后 8位,二进制 8 个 0 还是 16 进制 00 */

console.log(buf[1]);// 170 0xaa 控制台打印是 10 进制
console.log(buf[1].toString(16)); // aa 16 进制输出

var buf1 = Buffer.allocUnsafe(10); // <Buffer 31 34 11 c9 bf 02 00 00 49 34>
// allocUnsafe 创建 10 字节,但是不清空内存,之前别的程序使用的内存信息在这里面.可能有敏感信息

Buffer.from(str);// 将字符串转换成 Buffer 储存
js

base64 存储

let buf = Buffer.from('字符').toString('base64'); // 存储,转换成 base64
console.log(buf);// 5a2X56ym
let buf1 = Buffer.from(buf,'base64');// buf 是字符串 第二个参数以 base64 存储 
console.log(buf1.toString('utf-8'));// 字符

Buffer.alloc(size);// 创建一个指定大小的 Buffer
Buffer.allocUnsafe(size);// 创建一个指定大小的 buffer,可能包含敏感数据
buf.toString();// 将缓冲区的数据转换成字符串
Buffer.allocUnsafeSlow(size);// 慢,不安全的分配空间
Buffer.byteLength(string, 'utf8');// 获取一个字符串占用内存的大小,默认 utf-8
Buffer.compare(buf1, buf2);// 比较两个 Buffer 是否是同一个
Buffer.concat([buf1,buf2]);// 连接多个 Buffer
Buffer.isBuffer(obj);// 是否是一个 Buffer 返回 true/false
Buffer.isEncoding(encoding);// 返回是否支持 encoding true/false 
Buffer.isEncoding('utf-8');// true
Buffer.isEncoding('utf/8');// false
Buffer.poolSize ;// 缓冲池的预分配的内部 Buffer 实例的大小(以字节为单位)可以修改
js

Node.js FS 文件系统 (File System)

方法

fs.existsSync(path);// 检查一个文件是否存在 返回 true/false 不能检查目录

fs.stat(path,(e,stat) => { // 是文件还是目录
  stat.size;// 文件大小
  stat.isFile();// 是否是文件
  stat.isDirectory();// 是否是目录
})

fs.readFileSync(path);// 读取文件  文件不存在会报错
fs.writeFileSync(path,'123');// 写入文件(覆盖) 返回 undefined 文件不存在会自动创建
fs.unlinkSync(path); // 删除文件  返回 undefined  不存在会报错
fs.readdirSync(path[, options]);// 读取目录下的所有文件名 返回数组
fs.truncateSync(path[, len])// 截断文件 把文件设为 3 个字节,后面的内容截断 不存在会报错

fs.mkdirSync(path[, options])// 新建文件夹 已存在会报错
fs.rmdirSync(path[, options])// 删除文件夹 文件夹内有文件会报错 不存在会报错
fs.renameSync(oldPath, newPath)// 重命名 文件/目录名 旧路径至新路径可以实现移动文件
js

监听文件

  • filename:监听的文件名
  • options:配置​- interval:1000 每隔 1 秒监听一次
  • listener 回调函数,当文件发生变化时,回调函数会执行,会有两个参数​- curr 当前文件的状态
    • prev 修改前文件的状态​- 这两个对象都是 stats 对象
fs.watchFile(filename[, options], listener)
fs.watchFile('hello.txt',{interval : 1000},function(curr,prev){
  console.log('修改前文件大小' + prev.size);
  console.log('修改后文件大小' + curr.size);
})
js

流式文件读取

let rs = fs.createReadStream(path);// 创建可读流
let ws = fs.createWriteStream(path);// 创建可写流
rs.pipe(ws);// 可读流传输到可写流
rs.on('open',() => {});// 可读流打开
rs.once('close',() => {}); // 可读流关闭 可读流关闭后 调用 rs.end() 
ws.on('open',() => {});// 可写流打开
ws.once('close', () => {});// 可写流关闭
rs.on('data',function(data){
  console.log(data.length);// 查看每次读取到的字节
  ws.write(data);// 写入读取到的 data
})
js

flag操作符

  • r:读取文件,文件不存在则出现异常
  • r+:读写又件,又件不存在则出现异常
  • rs:在同步模式下打开文件用于读取
  • rs+:在同步模式下打开文件用于读写
  • w:打开文件用于写操作如果不存在则创建,如果存在则酸断
  • wx:打开文件用于写操作如果存在则打开失败
  • w+:打开文件用于读写如果不存在则创如果存在则载断
  • wx+:打开文件用于读写如果存在则打开失败
  • a:打开丈件用于遍加如果不存在则创建
  • ax:打开文件用于追加如果路径存在则失败
  • a+:打开文件进行读取和追加如果不存在则创建该文件
  • ax+:打开文件进行读取和追加如果路径存在则失败

Node.js url

URL 对象

返回与传统 parse 一样的对象

const u = new URL('https://www.baidu.com:8080?abc=ca&cb=qw#aa');
js

判断某个字符串是否是以指定的字符开头:startsWith() 字符串. startsWith(‘/ad’)

url.parse('https://www.baidu.com:8080/api.php?from=qian&soucces=123#lenst1',true)
js

返回一个对象,其中 query 键为 ? 后面查询的字符串

// 参数1 地址
// 参数2 是否对?后面的解析成对象,false不解析,就是字符串
// 参数3 在地址不知道http协议下,传入true(protocol\slashes\auth\host\port\hostname)可以解析,不传都是null

Url {
  protocol: 'https:',
  slashes: true,
  auth: null,
  host: 'www.baidu.com:8080',
  port: '8080',
  hostname: 'www.baidu.com',
  hash: '#lenst1',
  search: '?from=qian&soucces=123',
  query: 'from=qian&soucces=123',
  pathname: '/api.php',
  path: '/api.php?from=qian&soucces=123',
  href: 'https://www.baidu.com:8080/api.php?from=qian&soucces=123#lenst1'
}

// 将url对象解析成地址
url.format({protocol: 'https:',slashes: true,auth:...等});
// https://www.baidu.com:8080/api.php?from=qian&soucces=123#lenst1

// 将两端url解析成一个完整的url
url.resolve('http:// www.baidu.com','/api/list.php');
// http:// www.baidu.com/api/list.php
js

querystring

querystring.stringify(obj[, sep[, eq[, options]]]) // 将对象转换成字符串
// obj 对象 
// sep 键值对与键值对 之间的连接符号 默认'&'
// eq 键与值之间连接符号 默认'='

querystring.parse(str[, sep[, eq[, options]]]) // 将字符串转换成对象
  // 与字符串同理

querystring.escape(str) // 将字符串转换成字符编码
querystring.unescape(str)// 将字符编码转换成字符串
js

Node.js http 服务器

创建服务器

const http = require('http');
const server = http.createServer();// 创建服务器
// [参数1:配置信息][参数2:fun(request请求,response相应)]
// 返回 hppt.server对象

// 返回的对象,监听 req请求
server.on('request',(req,res) => {
  // request:浏览器请求信息 response:返回响应信息
  // 设置头文件 防止乱码
  res.writeHead(200,'ok',{'content-type' : 'text/html;charset=utf-8;'});

  // 参数1:200 [参数2:备注信息][参数3:配置信息,设置 utf-8 返回 ServerResponse 可用链式调用
  res.setHeader('content-type','text/html;charset=utf-8;');
  // 设置单个响应头的值 同上

  res.write('返回1'); // 返回响应的信息,可调用多次
  res.end('结束'); // 结束响应,必须、且只能调用一次;后续的代码不会执行
});

// 参数1:设置端口号 [参数2:回调]
server.listen(8888,() =>{
  console.log('server at 8888');
})
js

设置允许跨域

app.all('*', function(req, res, next) {
 // 设置允许跨域的域名,*代表允许任意域名跨域
  res.header("Access-Control-Allow-Origin", "*");
 // 允许的header类型
  res.header('Access-Control-Allow-Headers', 'Content-type');
 // 跨域允许的请求方式
  res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS,PATCH");
  next();
});
js

Node.js events 事件监听

const events = require('events');
// 需要先new构造函数
const eventsEmiter = new events();

eventsEmiter.on('aa',() => {
  console.log('自定义事件');
})

eventsEmiter.emit('aa');// 调用
eventsEmiter.once('cc',() => {
  console.log('自能调用一次后失效');
})

eventsEmiter.emit('cc');// 只能调用一次
js
评论
来发一针见血的评论吧!
表情

快来发表评论吧~

推荐文章
  • 测试文章

    20点赞10评论

  • webpack5(一)

    20点赞10评论