创建服务器
在根目录下创建server.js的文件,里面写如入以下代码:
// 请求nodejs自带的http模块
var http = require('http');
http.createServer(function (request, response) {
// 发送 HTTP 头部
// HTTP 状态值: 200 : OK
// 内容类型: text/plain
response.writeHead(200, {'Content-Type': 'text/plain'});
// 发送响应数据 "Hello World"
response.end('Hello World\n');
}).listen(8888);
// listen是用来指定端口号
// 终端打印如下信息
console.log('Server running at http://127.0.0.1:8888/');
使用node执行这个文件即可:
node server.js
// Server running at http://127.0.0.1:8888/
在 http://127.0.0.1:8888/上就会有
Node.js REPL(交互式解释器)
node命令进入REPL
ctrl + c - 退出当前终端。
ctrl + c 按下两次 - 退出 Node REPL。
ctrl + d - 退出 Node REPL.
向上/向下 键 - 查看输入的历史命令
tab 键 - 列出当前命令
.help - 列出使用命令
.break - 退出多行表达式
.clear - 退出多行表达式
.save filename - 保存当前的 Node REPL 会话到指定文件
.load filename - 载入当前 Node REPL 会话的文件内容。
异步(非阻塞)
var fs = require("fs");
fs.readFile('input.txt', function (err, data) {
if (err) return console.error(err);
console.log(data.toString());
});
console.log("程序执行结束!");
// $ node main.js
// 程序执行结束!
// 菜鸟教程官网地址:www.runoob.com
事件(event)
on进行事件与函数绑定绑定,emit进行事件触发
// 引入 events 模块
var events = require('events');
// 创建 eventEmitter 对象
var eventEmitter = new events.EventEmitter();
// 创建事件处理程序
var connectHandler = function connected() {
console.log('连接成功。');
// 触发 data_received 事件
eventEmitter.emit('data_received');
}
// 绑定 connection 事件处理程序
eventEmitter.on('connection', connectHandler);
// 使用匿名函数绑定 data_received 事件
eventEmitter.on('data_received', function(){
console.log('数据接收成功。');
});
// 触发 connection 事件
eventEmitter.emit('connection');
console.log("程序执行完毕。");
封装EventEmitter
使用方式
var events = require('events');
var emitter = new events.EventEmitter();
emitter.on('eventname',function(){})
....
EventEmitter属性
1. addListener(event, listener)(和js中的差不多)
2. on(event, listener)
3. once(event,listener) // 只监听一次
4. removeListener(event, listener)
5. removeAllListeners([event])
6. setMaxListeners(n) 默认情况下, EventEmitters 如果你添加的监听器超过 10 个就会输出警告信息。
7. listeners(event) 返回指定的监听器数组
8. emit(event, [arg1], [arg2], […])
Buffer
const buf = Buffer.from('runoob', 'ascii');
// 输出 72756e6f6f62
console.log(buf.toString('hex'));
// 输出 cnVub29i
console.log(buf.toString('base64'));
buffer实例Api
Buffer.alloc(size[, fill[, encoding]]): 返回一个指定大小的 Buffer 实例,如果没有设置 fill,则默认填满 0
Buffer.allocUnsafe(size): 返回一个指定大小的 Buffer 实例,但是它不会被初始化,所以它可能包含敏感的数据
Buffer.allocUnsafeSlow(size)
Buffer.from(array): 返回一个被 array 的值初始化的新的 Buffer 实例(传入的 array 的元素只能是数字,不然就会自动被 0 覆盖)
Buffer.from(arrayBuffer[, byteOffset[, length]]): 返回一个新建的与给定的 ArrayBuffer 共享同一内存的 Buffer。
Buffer.from(buffer): 复制传入的 Buffer 实例的数据,并返回一个新的 Buffer 实例
Buffer.from(string[, encoding]): 返回一个被 string 的值初始化的新的 Buffer 实例
写入缓存区
buf.write(string[, offset[, length]][, encoding])
参数介绍:
string - 写入缓冲区的字符串。
offset - 缓冲区开始写入的索引值,默认为 0 。
length - 写入的字节数,默认为 buffer.length
encoding - 使用的编码。默认为 'utf8' 。
读取缓存区
buf.toString([encoding[, start[, end]]])
encoding - 使用的编码。默认为 'utf8' 。
start - 指定开始读取的索引位置,默认为 0。
end - 结束位置,默认为缓冲区的末尾。
Compare
var buffer1 = Buffer.from('ABC');
var buffer2 = Buffer.from('ABCD');
var result = buffer1.compare(buffer2);
if(result < 0) {
console.log(buffer1 + " 在 " + buffer2 + "之前");
}else if(result == 0){
console.log(buffer1 + " 与 " + buffer2 + "相同");
}else {
console.log(buffer1 + " 在 " + buffer2 + "之后");
}
// ABC在ABCD之前
Stream
读取
var fs = require("fs");
var data = '';
// 创建可读流
var readerStream = fs.createReadStream('input.txt');
// 设置编码为 utf8。
readerStream.setEncoding('UTF8');
// 处理流事件 --> data, end, and error
readerStream.on('data', function(chunk) {
data += chunk;
});
readerStream.on('end',function(){
console.log(data);
});
readerStream.on('error', function(err){
console.log(err.stack);
});
console.log("程序执行完毕");
写入
在这里插入代码片var fs = require("fs");
var data = 'aaaaa';
// 创建一个可以写入的流,写入到文件 output.txt 中
var writerStream = fs.createWriteStream('output.txt');
// 使用 utf8 编码写入数据
writerStream.write(data,'UTF8');
// 标记文件末尾
writerStream.end();
// 处理流事件 --> finish、error
writerStream.on('finish', function() {
console.log("写入完成。");
});
writerStream.on('error', function(err){
console.log(err.stack);
});
console.log("程序执行完毕");
pipe管道流(从一个文件读取到另一个文件中,也就是文件的复制)
var fs = require("fs");
// 创建一个可读流
var readerStream = fs.createReadStream('input.txt');
// 创建一个可写流
var writerStream = fs.createWriteStream('output.txt');
// 管道读写操作
// 读取 input.txt 文件内容,并将内容写入到 output.txt 文件中
readerStream.pipe(writerStream);
console.log("程序执行完毕");
链式流(说是主要用于管道操作,实际还没太理解)
// 压缩
var fs = require("fs");
var zlib = require('zlib');
// 压缩 input.txt 文件为 input.txt.gz
fs.createReadStream('input.txt')
.pipe(zlib.createGzip())
.pipe(fs.createWriteStream('input.txt.gz'));
console.log("文件压缩完成。");
// 解压
var fs = require("fs");
var zlib = require('zlib');
// 解压 input.txt.gz 文件为 input.txt
fs.createReadStream('input.txt.gz')
.pipe(zlib.createGunzip())
.pipe(fs.createWriteStream('input.txt'));
console.log("文件解压完成。");
模块
export
在学习模块前,必须了解export是什么,vue中经常用到,但是大多数不用考虑是怎么用,干什么的,按着来就行了
概念: 首先,export是用来将文件内的变量或数据传出去的,可以传变量,可以传函数,也可以传对象,甚至可以重命名再传出去(用as)
要求: 必须再模块顶层,不能被任何东西包裹
// 使用模块
var hello = require('./hello');
hello.world();
// hello.js
exports.world = function() {
console.log('Hello World');
}
模块加载顺序
缓存>原生模块>文件模块
Utils
常用工具
util.callbackify(fn)
异常优先的回调函数,参数有两个(err,value)如果promise解决,err为null
const util = require('util');
async function fn() {
return 'hello world';
}
const callbackFunction = util.callbackify(fn);
callbackFunction((err, ret) => {
if (err) throw err;
console.log(ret);
});
util.inherits
继承
util.inherits(子, 父);
// 注意这里的子只继承了父在原型中定义的函数。
util.inspect
将对象等转成字符串
util.inspect(object,[showHidden],[depth],[colors])
showhidden默认是false,设为true显示全部隐藏信息(比如函数内容);
depth是递归深度,默认是2层,设为null全部递归遍历;
color如果是true输出格式就是ANSI的颜色编码
判断格式
util.isArray(object)
util.isRegExp(object)
util.isDate(object)
get/post
get
请求
var http = require('http');
var url = require('url');
var util = require('util');
http.createServer(function(req, res){
res.writeHead(200, {'Content-Type': 'text/plain; charset=utf-8'});
res.end(util.inspect(url.parse(req.url, true)));
}).listen(3000);
parse是用来获取地址的,包括地址后面的参数部分,实例如下:
const url = require('url');
const urlString = 'https://www.example.com/search?q=node.js&page=1';
const parsedUrl = url.parse(urlString, true);
// true表示解析字符串
console.log(parsedUrl.protocol); // 输出:https:
console.log(parsedUrl.host); // 输出:www.example.com
console.log(parsedUrl.pathname); // 输出:/search
console.log(parsedUrl.query); // 输出:{ q: 'node.js', page: '1' }
获取数据
var http = require('http');
var url = require('url');
var util = require('util');
http.createServer(function(req, res){
res.writeHead(200, {'Content-Type': 'text/plain'});
// 解析 url 参数
var params = url.parse(req.url, true).query;
res.write("网站名:" + params.name);
res.write("\n");
res.write("网站 URL:" + params.url);
res.end();
}).listen(3000);
post
获取
var http = require('http');
var querystring = require('querystring');
var util = require('util');
http.createServer(function(req, res){
// 定义了一个post变量,用于暂存请求体的信息
var post = '';
// 通过req的data事件监听函数,每当接受到请求体的数据,就累加到post变量中
req.on('data', function(chunk){
post += chunk;
});
// 在end事件触发后,通过querystring.parse将post解析为真正的POST请求格式,然后向客户端返回。
req.on('end', function(){
post = querystring.parse(post);
res.end(util.inspect(post));
});
}).listen(3000);
接受参数
var http = require('http');
var querystring = require('querystring');
var postHTML = 'html表单';
http.createServer(function (req, res) {
var body = "";
req.on('data', function (chunk) {
body += chunk;
});
req.on('end', function () {
// 解析参数
body = querystring.parse(body);
// 设置响应头部信息及编码
res.writeHead(200, {'Content-Type': 'text/html; charset=utf8'});
if(body.name && body.url) { // 输出提交的数据
res.write("网站名:" + body.name);
res.write("<br>");
res.write("网站 URL:" + body.url);
} else { // 输出表单
res.write(postHTML);
}
res.end();
});
}).listen(3000);
Express框架
var express = require('express');
var app = express();
app.get('/', function (req, res) {
res.send('Hello World');
})
res和req都有各自的特殊的属性,可以去官网查看