//一 回调函数

//require---命令
//Node 使用了大量的回调函数,Node 所有 API 都支持回调函数。
//例如,我们可以一边读取文件,一边执行其他命令,在文件读取完成后,我们将文件内容作为回调函数的参数返回。
//这样在执行代码时就没有阻塞或等待文件 I/O 操作。这就大大提高了 Node.js 的性能,可以处理大量的并发请求。

//阻塞状态
/*var fs=require("fs");
var data=fs.readFileSync("input.txt");
console.log(data.toString());
console.log("程序执行结束!");*/

//非阻塞状态
/*var fs=require("fs");
fs.readFile('input.txt',function(err,data){
if (err) return console.error(err);
console.log(data.toString());
});
console.log("程序执行结束!");*/

//二 事件循环

/*eventEmitters(事件触发器监听器)------events(事件) -----event loop(循环)---eventHandler(事件处理)
Node.js 单线程类似进入一个while(true)的事件循环,直到没有事件观察者退出,每个异步事件都生成一个事件观察者,
如果有事件发生就调用该回调函数.*/

//事件驱动程序
/*使用事件驱动模型,当web server接收到请求,就把它关闭然后进行处理,然后去服务下一个web请求。

当这个请求完成,它被放回处理队列,当到达队列开头,这个结果被返回给用户。

这个模型非常高效可扩展性非常强,因为webserver一直接受请求而不等待任何读写操作。(这也被称之为非阻塞式IO或者事件驱动IO)

在事件驱动模型中,会生成一个主循环来监听事件,当检测到事件时触发回调函数。*/

//三 eventEmitter
// 引入 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("程序执行完毕。");
var events = require('events');
var eventEmitter = new events.EventEmitter();

// 监听器 #1
var listener1 = function listener1() {
console.log('监听器 listener1 执行。');
}

// 监听器 #2
var listener2 = function listener2() {
console.log('监听器 listener2 执行。');
}

// 绑定 connection 事件,处理函数为 listener1
eventEmitter.addListener('connection', listener1);

// 绑定 connection 事件,处理函数为 listener2
eventEmitter.on('connection', listener2);

var eventListeners = eventEmitter.listenerCount('connection');
console.log(eventListeners + " 个监听器监听连接事件。");

// 处理 connection 事件
eventEmitter.emit('connection');

// 移除监绑定的 listener1 函数
eventEmitter.removeListener('connection', listener1);
console.log("listener1 不再受监听。");

// 触发连接事件
eventEmitter.emit('connection');

eventListeners = eventEmitter.listenerCount('connection');
console.log(eventListeners + " 个监听器监听连接事件。");

console.log("程序执行完毕。");*/

//四 buffer

//Buffer 实例一般用于表示编码字符的序列,比如 UTF-8 、 UCS2 、 Base64 、或十六进制编码的数据。
//通过使用显式的字符编码,就可以在 Buffer 实例与普通的 JavaScript 字符串之间进行相互转换。
/*ascii - 仅支持 7 位 ASCII 数据。如果设置去掉高位的话,这种编码是非常快的。

utf8 - 多字节编码的 Unicode 字符。许多网页和其他文档格式都使用 UTF-8 。

utf16le - 2 或 4 个字节,小字节序编码的 Unicode 字符。支持代理对(U+10000 至 U+10FFFF)。

ucs2 - utf16le 的别名。

base64 - Base64 编码。

latin1 - 一种把 Buffer 编码成一字节编码的字符串的方式。

binary - latin1 的别名。

hex - 将每个字节编码为两个十六进制字符*/

/*const buf = Buffer.from('runoob','ascii');

console.log(buf.toString('hex'));//转进制

console.log(buf.toString('base64'));//转码

// 创建一个长度为 10、且用 0 填充的 Buffer。
const buf1 = Buffer.alloc(10);

// 创建一个长度为 10、且用 0x1 填充的 Buffer。
const buf2 = Buffer.alloc(10, 1);

// 创建一个长度为 10、且未初始化的 Buffer。
// 这个方法比调用 Buffer.alloc() 更快,
// 但返回的 Buffer 实例可能包含旧数据,
// 因此需要使用 fill() 或 write() 重写。
const buf3 = Buffer.allocUnsafe(10);

// 创建一个包含 [0x1, 0x2, 0x3] 的 Buffer。
const buf4 = Buffer.from([1, 2, 3]);

// 创建一个包含 UTF-8 字节 [0x74, 0xc3, 0xa9, 0x73, 0x74] 的 Buffer。
const buf5 = Buffer.from('tést');

// 创建一个包含 Latin-1 字节 [0x74, 0xe9, 0x73, 0x74] 的 Buffer。
const buf6 = Buffer.from('tést', 'latin1');*/

//写入缓冲区
//buf.write(string[, offset[, length]][, encoding])
/*
参数:string - 写入缓冲区的字符串。

offset - 缓冲区开始写入的索引值,默认为 0 。

length - 写入的字节数,默认为 buffer.length

encoding - 使用的编码。默认为 'utf8' 。

根据 encoding 的字符编码写入 string 到 buf 中的 offset 位置。 length 参数是写入的字节数。
如果 buf 没有足够的空间保存整个字符串,则只会写入 string 的一部分。 只部分解码的字符不会被写入。
返回值
返回实际写入的大小。如果 buffer 空间不足, 则只会写入部分字符串。

buf=Buffer.alloc(256);
len=buf.write("www.runoob.com");
console.log("写入字节数:"+len);//输出14*/

//从缓冲区读取数据
/*buf.toString([encoding[, start[, end]]])
参数:encoding - 使用的编码。默认为 'utf8' 。

start - 指定开始读取的索引位置,默认为 0。

end - 结束位置,默认为缓冲区的末尾
返回值
解码缓冲区数据并使用指定的编码返回字符串。

buf=Buffer.alloc(26);
for (var i=0;i<26;i++){
buf[i]=i+97;
}
console.log(buf.toString('ascii'));
console.log(buf.toString('ascii',0,5));
console.log(buf.toString('utf8',0,5));
console.log(buf.toString(undefined,0,5));*/

//buffer转为json对象
//当字符串化一个 Buffer 实例时,JSON.stringify() 会隐式地调用该 toJSON()。
//buf.toJSON();
/*const buf=Buffer.from([1, 2, 3, 4, 5]);
const json=JSON.stringify(buf);
console.log(json);//输出:{"type":"Buffer","data":[1,2,3,4,5]}
const copy=JSON.parse(json,(key,value)=>{
return value && value.type === 'Buffer' ?
Buffer.from(value.data) :
value;
});
//输出:<Buffer 01 02 03 04 05>
console.log(copy);*/

/*
缓冲区合并及比较.拷贝
*/
/*var b1=Buffer.from('菜鸟');
var b2=Buffer.from('cainiaojiaocheng');
var b3=Buffer.concat([b1,b2]);
console.log(b3.toString());

var buffer1 = Buffer.from('EF');
var buffer2 = Buffer.from('ABCD');
var result = buffer1.compare(buffer2);
console.log(result);

var buf1 = Buffer.from('abcdefghijkl');
var buf2 = Buffer.from('RUNOOB');

//将 buf2 插入到 buf1 指定位置上
buf2.copy(buf1, 2);
//输出abRUNOOBijkl
console.log(buf1.toString());

var buffer1 = Buffer.from('runoob');
// 剪切缓冲区
var buffer2 = buffer1.slice(0,2);

//输出ru
console.log("buffer2 content: " + buffer2.toString());*/

//五stream(流)

/*
Stream 有四种流类型:

Readable - 可读操作。

Writable - 可写操作。

Duplex - 可读可写操作.

Transform - 操作被写入数据,然后读出结果。

所有的 Stream 对象都是 EventEmitter 的实例。常用的事件有:

data - 当有数据可读时触发。

end - 没有更多的数据可读时触发。

error - 在接收和写入过程中发生错误时触发。

finish - 所有数据已被写入到底层系统时触发。
*/

/*
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;
console.log(0)
});

readerStream.on('end',function(){
console.log(data);
});

readerStream.on('error', function(err){
console.log(err.stack);
});

console.log("程序执行完毕");*/

//写入流
/*
var fs=require("fs");
var data ='菜鸟教程官方网址:www.runoob.com';

//创建流写入到文件output.txt中

var writerStream=fs.createWriteStream('output.txt');

//使用utf8编码写入数据
writerStream.write(data,'utf8');
// 标记文件末尾
writerStream.end();

// 处理流事件 --> data, end, and 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("文件解压完成。");
*/

//node.js模块系统

/*
var hello=require('./hello');//获取外部的hello.js文件
hello.world();//执行hello.js文件中的
*/
//hello.js
/*
var Hello = require('./hello');
hello = new Hello();
hello.setName('BYVoid');
hello.sayHello();
*/

//函数
/*
var http = require("http");

http.createServer(function(request, response) {
response.writeHead(200, {"Content-Type": "text/plain"});
response.write("Hello World");
response.end();
}).listen(8888);
//测试网页访问localhost:8888页面输出Hello World*/

//路由
/*router.js与index.js
var http = require("http");
var url = require("url");

function start(route) {
function onRequest(request, response) {
var pathname = url.parse(request.url).pathname;
console.log("Request for " + pathname + " received.");

route(pathname);

response.writeHead(200, {"Content-Type": "text/plain"});
response.write("Hello World");
response.end();
}

http.createServer(onRequest).listen(8888);
console.log("Server has started.");
}

exports.start = start;
*/

//全局变量
/*
当你定义一个全局变量时,这个变量同时也会成为全局对象的属性,反之亦然。
需要注 意的是,在 Node.js 中你不可能在最外层定义变量,因为所有用户代码都是属于当前模块的,
而模块本身不是最外层上下文。
注意: 永远使用 var 定义变量以避免引入全局变量,因为全局变量会污染 命名空间,提高代码的耦合风险。
*/

/*
//__filename当前正在执行的脚本的文件名。它将输出文件所在位置的绝对路径,且和命令行参数所指定的文件名不一定相同。
// 如果在模块中,返回的值是模块文件的路径。
console.log( __filename );
//__dirname 表示当前执行脚本所在的目录。
console.log( __dirname );

function printHello(){
console.log( "Hello, World! setTimeout");
}
// 两秒后执行以上函数
//setTimeout(cb, ms) 全局函数在指定的毫秒(ms)数后执行指定函数(cb)。:setTimeout() 只执行一次指定函数。
var t=setTimeout(printHello, 2000);
// 清除定时器
clearTimeout(t);

function printHello(){
console.log( "Hello, World! setInterval");
}
// 两秒后执行以上函数,循环执行
setInterval(printHello, 2000);

// 输出当前目录
console.log('当前目录: ' + process.cwd());

// 输出当前版本
console.log('当前版本: ' + process.version);

// 输出内存使用情况
console.log(process.memoryUsage());

// 输出到终端
process.stdout.write("Hello World!" + "\n");

// 通过参数读取
process.argv.forEach(function(val, index, array) {
console.log(index + ': ' + val);
});

// 获取执行路径
console.log(process.execPath);

// 平台信息
console.log(process.platform);*/

//常用工具

//util.inherits 是一个实现对象间原型继承 的函数。
//注意:Sub 仅仅继承了Base 在原型中定义的函数,而构造函数内部创造的 base 属 性
//和 sayHello 函数都没有被 Sub 继承。
/*
var util = require('util');
function Base() {
this.name = 'base';
this.base = 1991;
this.sayHello = function() {
console.log('Hello ' + this.name);
};
}
Base.prototype.showName = function() {
console.log(this.name);
};
function Sub() {
this.name = 'sub';
}
util.inherits(Sub, Base);
var objBase = new Base();
objBase.showName();
objBase.sayHello();
console.log(objBase);
var objSub = new Sub();
objSub.showName();
objSub.sayHello(); //不能继承构造函数内的属性和方法
console.log(objSub);
*/

//util.inspect是一个将任意对象转换 为字符串的方法,通常用于调试和错误输出。
//它至少接受一个参数 object,即要转换的对象。
//util.inspect(object,[showHidden],[depth],[colors])
//showHidden 是一个可选参数,如果值为 true,将会输出更多隐藏信息。
//depth 表示最大递归的层数,
/*
var util = require('util');
function Person() {
this.name = 'byvoid';
this.toString = function() {
return this.name;
};
}
var obj = new Person();
console.log(util.inspect(obj));
console.log(util.inspect(obj, true));

//util.isArray(object)
//如果给定的参数 "object" 是一个数组返回true,否则返回false。
var util = require('util');

console.log(util.isArray([]))
// true
util.isArray(new Array)
console.log(util.isArray(new Array))
// true
util.isArray({})
console.log(util.isArray({}))
// false

//util.isRegExp(object)如果给定的参数 "object" 是一个正则表达式返回true,否则返回false。
//util.isDate(object)如果给定的参数 "object" 是一个日期返回true,否则返回false。
//util.isError(object)如果给定的参数 "object" 是一个错误对象返回true,否则返回false。
*/

//文件系统

/*
var fs=require("fs");
// 异步读取
fs.readFile('input.txt', function (err, data) {
if (err) {
return console.error(err);
}
console.log("异步读取: " + data.toString());
});

// 同步读取
var data = fs.readFileSync('input.txt');
console.log("同步读取: " + data.toString());

console.log("程序执行完毕。");
*/

//打开文件fs.open(path, flags[, mode], callback)
/*
path - 文件的路径。

flags - 文件打开的行为。具体值详见下文。

mode - 设置文件模式(权限),文件创建默认权限为 0666(可读,可写)。

callback - 回调函数,带有两个参数如:callback(err, fd)。
var fs = require("fs");
// 异步打开文件
console.log("准备打开文件!");
fs.open('input.txt', 'r+', function(err, fd) {
if (err) {
return console.error(err);
}
console.log("文件打开成功!");
});*/

//获取文件信息fs.stat(path, callback)
/*
var fs = require("fs");
fs.stat('/Program Files/nodejs/test/mains.js', function (err, stats) {
console.log(stats.isFile()); //true
})

console.log("准备打开文件!");
fs.stat('input.txt', function (err, stats) {
if (err) {
return console.error(err);
}
console.log(stats);
console.log("读取文件信息成功!");

// 检测文件类型
console.log("是否为文件(isFile) ? " + stats.isFile());
console.log("是否为目录(isDirectory) ? " + stats.isDirectory());
});*/

//写入文件fs.writeFile(file, data[, options], callback)
/*
var fs = require("fs");

console.log("准备写入文件");
fs.writeFile('input.txt', '我是通 过fs.writeFile 写入文件的内容', function(err) {
if (err) {
return console.error(err);
}
console.log("数据写入成功!");
console.log("--------我是分割线-------------")
console.log("读取写入的数据!");
fs.readFile('input.txt', function (err, data) {
if (err) {
return console.error(err);
}
console.log("异步读取文件数据: " + data.toString());
});
});*/

//文件读取fs.read(fd, buffer, offset, length, position, callback)
/*
var fs = require("fs");
var buf = new Buffer.alloc(1024);

console.log("准备打开已存在的文件!");
//r+以读写模式打开文件。如果文件不存在抛出异常
fs.open('input.txt', 'r+', function(err, fd) {
if (err) {
return console.error(err);
}
console.log("文件打开成功!");
console.log("准备读取文件:");
fs.read(fd, buf, 0, buf.length, 0, function(err, bytes){
if (err){
console.log(err);
}
console.log(bytes + " 字节被读取");

// 仅输出读取的字节
if(bytes > 0){
console.log(buf.slice(0, bytes).toString());
}
});
});*/

//关闭文件fs.close(fd, callback)该方法使用了文件描述符来读取文件。
/*
var fs = require("fs");
var buf = new Buffer.alloc(1024);

console.log("准备打开文件!");
fs.open('input.txt', 'r+', function(err, fd) {
if (err) {
return console.error(err);
}
console.log("文件打开成功!");
console.log("准备读取文件!");
fs.read(fd, buf, 0, buf.length, 0, function(err, bytes){
if (err){
console.log(err);
}

// 仅输出读取的字节
if(bytes > 0){
console.log(buf.slice(0, bytes).toString());
}

// 关闭文件
fs.close(fd, function(err){
if (err){
console.log(err);
}
console.log("文件关闭成功");
});
});
});*/

//截取文件fs.ftruncate(fd, len, callback)
/*
var fs = require("fs");
var buf = new Buffer.alloc(1024);

console.log("准备打开文件!");
fs.open('input.txt', 'r+', function(err, fd) {
if (err) {
return console.error(err);
}
console.log("文件打开成功!");
console.log("截取10字节内的文件内容,超出部分将被去除。");

// 截取文件
fs.ftruncate(fd, 10, function(err){
if (err){
console.log(err);
}
console.log("文件截取成功。");
console.log("读取相同的文件");
fs.read(fd, buf, 0, buf.length, 0, function(err, bytes){
if (err){
console.log(err);
}

// 仅输出读取的字节
if(bytes > 0){
console.log(buf.slice(0, bytes).toString());
}

// 关闭文件
fs.close(fd, function(err){
if (err){
console.log(err);
}
console.log("文件关闭成功!");
});
});
});
});*/

//删除文件fs.unlink(path, callback)
/*
var fs = require("fs");

console.log("准备删除文件!");
fs.unlink('input.txt', function(err) {
if (err) {
return console.error(err);
}
console.log("文件删除成功!");
});*/

//创建目录fs.mkdir(path[, options], callback)
/*
var fs = require("fs");
// tmp 目录必须存在不存在会报错
console.log("创建目录 /tmp/test/");
fs.mkdir("/tmp/test/",function(err){
if (err) {
return console.error(err);
}
console.log("目录创建成功。");
});*/

//读取目录fs.readdir(path, callback)
/*
var fs = require("fs");

console.log("查看 /tmp 目录");
fs.readdir("/tmp/",function(err, files){
if (err) {
return console.error(err);
}
files.forEach( function (file){
console.log( file );
});
});*/
//删除目录fs.rmdir(path, callback)
/*
var fs = require("fs");
// 执行前创建一个空的 /tmp/test 目录
console.log("准备删除目录 /tmp/test");
fs.rmdir("/tmp/test",function(err){
if (err) {
return console.error(err);
}
console.log("读取 /tmp 目录");
fs.readdir("/tmp/",function(err, files){
if (err) {
return console.error(err);
}
files.forEach( function (file){
console.log( file );
});
});
});*/

//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);*/

//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'});

// 解析 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 util = require('util');
var querystring = require('querystring');

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><head><meta charset="utf-8"><title>菜鸟教程 Node.js 实例</title></head>' +
'<body>' +
'<form method="post">' +
'网站名: <input name="name"><br>' +
'网站 URL: <input name="url"><br>' +
'<input type="submit">' +
'</form>' +
'</body></html>';

http.createServer(function (req, res) {
var body = "";
req.on('data', function (chunk) {
console.log(chunk);
body += chunk;
console.log(0);
console.log(body);
});
req.on('end', function () {
console.log(1);
// 解析参数
body = querystring.parse(body);
// 设置响应头部信息及编码
res.writeHead(200, {'Content-Type': 'text/html; charset=utf8'});

if(body.name && body.url) { // 输出提交的数据
console.log(3);
res.write("网站名:" + body.name);
res.write("<br>");
res.write("网站 URL:" + body.url);
} else { // 输出表单
console.log(4);
res.write(postHTML);
}
res.end();
});
}).listen(3000);*/

//工具模块

//os模块 提供基本的系统操作函数。

//path模块 于处理文件路径的小工具

//net模块 用于底层的网络通信。提供了服务端和客户端的的操作。

//DNS用于解析域名

//Domain简化异步代码的异常处理 可以捕捉try catch无法捕捉的

/*
var os=require("os");
//系统操作函数。

console.log("操作系统的默认临时文件夹"+os.tmpdir());

console.log("CPU 的字节序,可能的是 BE 或 LE。"+os.endianness());

console.log("操作系统的主机名。"+os.hostname());

console.log("操作系统名"+os.type());

console.log("编译时的操作系统名"+os.platform());

console.log("操作系统 CPU 架构,可能的值有 x64、arm 和 ia32。"+os.arch());

console.log("操作系统的发行版本。"+os.release());

console.log("操作系统运行的时间,以秒为单位。"+os.uptime());

console.log("一个包含 1、5、15 分钟平均负载的数组。"+os.loadavg());

console.log("系统内存总量,单位为字节。"+os.totalmem());

console.log("操作系统空闲内存量,单位是字节。"+os.freemem());

console.log("一个对象数组,包含所安装的每个 CPU/内核的信息:型号、"+
"速度(单位 MHz)、时间(一个包含 user、nice、sys、idle "+
"和 irq 所使用 CPU/内核毫秒数的对象)。"+os.cpus());

console.log("获得网络接口列表。"+os.networkInterfaces());*/

//web模块
//使用 HTTP 服务器或客户端功能必须调用 http 模块,

// 创建服务器
/*
var http = require('http');
var fs = require('fs');
var url = require('url');
http.createServer( function (request, response) {
// 解析请求,包括文件名
var pathname = url.parse(request.url).pathname;

// 输出请求的文件名
console.log("Request for " + pathname + " received.");

// 从文件系统中读取请求的文件内容
fs.readFile(pathname.substr(1), function (err, data) {
if (err) {
console.log(err);
// HTTP 状态码: 404 : NOT FOUND
// Content Type: text/plain
response.writeHead(404, {'Content-Type': 'text/html'});
}else{
// HTTP 状态码: 200 : OK
// Content Type: text/plain
response.writeHead(200, {'Content-Type': 'text/html'});

// 响应文件内容
response.write(data.toString());
}
// 发送响应数据
response.end();
});
}).listen(8080);

// 控制台会输出以下信息
console.log('Server running at http://127.0.0.1:8080/');*/

//创建客户端

var http = require('http');

// 用于请求的选项
var options = {
host: 'localhost',
port: '8080',
path: '/index.html'
};

// 处理响应的回调函数
var callback = function(response){
// 不断更新数据
var body = '';
response.on('data', function(data) {
body += data;
});

response.on('end', function() {
// 数据接收完成
console.log(body);
});
}
// 向服务端发送请求
var req = http.request(options, callback);
req.end();

nodejs----初期学习笔记的更多相关文章

  1. nodejs入门学习笔记一——一个完整的http路由服务实现

    开始学习nodejs! 参考书籍:The Node Beginner Book ,所有问题和讨论都围绕本书. 1.学习nodejs需要具备的基础知识: js基本语法,基本上写过前端的都能满足,原生js ...

  2. NodeJS (npm) 学习笔记

    零, npm是nodeJS的包管理器,下载nodeJS后会自动安装好npm. 一,windows下安装 nodeJS并配置(以及angular安装相关问题) 1, 下载安装 https://nodej ...

  3. 【nodejs】学习笔记

    学习链接:http://www.cnblogs.com/zhongweiv/p/nodejs_environment.html (一)简介及环境安装 Node.js是让Javascript脱离浏览器运 ...

  4. nodejs入门学习笔记二——解决阻塞问题

    在最开始,我们要弄清楚node会什么会存在阻塞? node是这么标榜自己的:“在node中除了代码,所有一切都是并行执行的!” 意思是,Node.js可以在不新增额外线程的情况下,依然可以对任务进行并 ...

  5. Nodejs学习笔记(四)——支持Mongodb

    前言:回顾前面零零碎碎写的三篇挂着Nodejs学习笔记的文章,着实有点名不副实,当然,这篇可能还是要继续走着离主线越走越远的路子,从简短的介绍什么是Nodejs,到如何寻找一个可以调试的Nodejs ...

  6. Nodejs学习笔记(三)——一张图看懂Nodejs建站

    前言:一条线,竖着放,如果做不到精进至深,那就旋转90°,至少也图个幅度宽广. 通俗解释上面的胡言乱语:还没学会爬,就学起走了?! 继上篇<Nodejs学习笔记(二)——Eclipse中运行调试 ...

  7. Nodejs学习笔记(二)——Eclipse中运行调试Nodejs

    前篇<Nodejs学习笔记(一)——初识Nodejs>主要介绍了在搭建node环境过程中遇到的小问题以及搭建Eclipse开发Node环境的前提步骤.本篇主要介绍如何在Eclipse中运行 ...

  8. NodeJS学习笔记之Connect中间件模块(一)

    NodeJS学习笔记之Connect中间件模块(一) http://www.jb51.net/article/60430.htm NodeJS学习笔记之Connect中间件模块(二) http://w ...

  9. Nodejs学习笔记(六)--- Node.js + Express 构建网站预备知识

    目录 前言 新建express项目并自定义路由规则 如何提取页面中的公共部分? 如何提交表单并接收参数? GET 方式 POST 方式 如何字符串加密? 如何使用session? 如何使用cookie ...

  10. nodejs学习笔记<一>安装及环境搭建

    零零散散学了几天nodejs,进度一直停滞不前,今天沉下心来好好看了下nodejs的介绍和代码.自己也试着玩了下,算是有点入门了. 这里来做个学习笔记. ——————————————————————— ...

随机推荐

  1. IdentityServer4授权类型(GrantType)对应的返回类型(ResponseType)

    授权类型(GrantyType) 返回类型(ResponseType) authorization_code code implicit token implicit id_token implici ...

  2. [shell]输出内容到剪切板

    commandline和GUI下的clipboard的交互Mac下echo $PATH | pbcopy,copy to clipboardecho "$(pbpaste -Prefer t ...

  3. PHP深入浅出之命名空间(Namespace)的使用详解

    对于命名空间,官方文档已经说得很详细[查看],我在这里做了一下实践和总结. 命名空间一个最明确的目的就是解决重名问题,PHP中不允许两个函数或者类出现相同的名字,否则会产生一个致命的错误.这种情况下只 ...

  4. 2_Linux操作系统和基础命令行

    非图形页面下执行程序GUI接口CLI接口 #输入命令,给出执行文件的路径 命令提示符,prompt(表示可以立即输入命令了) 命令提示符通过bash(shell)运行程序来展示的 #:root #就是 ...

  5. 微软官方的Windowsphone社区

    微软官方的Windowsphone社区 http://answers.microsoft.com/zh-hans/winphone/forum/wp8?tab=Threads http://answe ...

  6. python 警惕 IEEE 754标准

    双精度浮点数格式,即IEEE 754标准 >>> 0.1+0.2 0.30000000000000004 >>> (0.1+0.2)==0.3 False > ...

  7. 使用python内置库pytesseract实现图片验证码的识别

    环境准备: 1.安装Tesseract模块 git文档地址:https://digi.bib.uni-mannheim.de/tesseract/ 下载后就是一个exe安装包,直接右击安装即可,安装完 ...

  8. IDEA复制某个类的包名路径

    在对应的类中右键: 然后看图:

  9. Dynamic networks | 动态网络

    Dynamic networks reveal key players in aging 系统生物学中的网络分析 网络的拓扑结构:topological properties, 网络的度:whole ...

  10. C# 实现邮件收取发送功能

    .Net调用QQ邮箱发送邮件   话说网上发送邮件的代码很多,但是我由于不细心,导致拿别人的代码发送邮件老是失败,今天就说说几个要注意的地方吧!!! ? 1 2 3 4 5 6 7 8 9 10 11 ...