node.js 模块引入
require 引入模块-commonjs规范
核心模块
require('http');// 引入 http 模块
js
- 引入的模块会先从当前目录 node_modules 找,没有继续往上一级目录找,直到根目录,没有则报错
- 文件模块:一个模块就是一个js文件
- 引入的是路径必须以 ./ 或 …/ 开头
- 引入后返回一个对象,返回的就是引入模块的返回值
var md = require('./02-module.js');// 引入本地模块 .js可以省略
js
每一个 js 文件模块都有一个文件作用域,无法返回引入模块的变量
exports 暴露给外部的变量
exports.变量名 = '';// 另一个文件即可访问该变量
js
引入自定义模块
- node_modules 下文件夹名字为模块名字, require 引入文件夹名字
- nodejs会自动找到文件夹下的 index.js 文件。如果不是 index 会报错
- 修改模块文件夹下 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