Node.js 多进程
Node.js 是以单线程的模式运行 事件驱动来处理并发 多核 cpu 的系统上创建多个子进程,从而提高性能 Node.js RESTful API REST即表述性状态传递 表述性状态转移是一组架构约束条件和原则。 REST是设计风格而不是标准。REST通常基于使用HTTP,URI,和XML(标准通用标记语言下的一个子集)以及HTML(标准通用标记语言下的一个应用)这些现有的广泛流行的协议和标准。REST 通常使用 JSON 数据格式。HTTP 方法以下为 REST 基本架构的四个方法: GET - 用于获取数据。 PUT - 用于更新或添加数据。 DELETE - 用于删除数据。 POST - 用于添加数据。 Node.js Express 框架 Express 是一个简洁而灵活的 node.js Web应用框架, 提供了一系列强大特性帮助你创建各种 Web 应用,和丰富的 HTTP 工具。 使用 Express 可以快速地搭建一个完整功能的网站。Express 框架核心特性:
可以设置中间件来响应 HTTP 请求。 定义了路由表用于执行不同的 HTTP 请求动作。 可以通过向模板传递参数来动态渲染 HTML 页面。安装 Express cnpm install express --savecnpm install body-parser --save
//处理 JSON, Raw, Text 和 URL 编码的数据cnpm install cookie-parser --save //解析Cookie的工具,转成对象cnpm install multer --save //enctype="multipart/form-data"(设置表单的MIME编码)查看下 express 使用的版本号
cnpm list express实例 var express = require('express'); var app = express();app.get('/', function (req, res) {
res.send('Hello World'); }) var server = app.listen(8081, function () { var host = server.address().address var port = server.address().port console.log("应用实例,访问地址为 http://%s:%s", host, port) }) Node.js Web 模块 Web服务器一般指网站服务器,是指驻留于因特网上某种类型计算机的程序,Web服务器的基本功能就是提供Web信息浏览服务。它只需支持HTTP协议、HTML文档格式及URL,与客户端的网络浏览器配合。大多数 web 服务器都支持服务端的脚本语言(php、python、ruby)等,并通过脚本语言从数据库获取数据,将结果返回给客户端浏览器。
目前最主流的三个Web服务器是Apache、Nginx、IIS。
Node 创建 Web 服务器
var http = require('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(8888);// 控制台会输出以下信息
console.log('Server running at http://127.0.0.1:8888/'); Node.js 工具模块 在 Node.js 模块库中有很多好用的模块。 OS 模块 提供基本的系统操作函数。 Path 模块 提供了处理和转换文件路径的工具。 Net 模块 用于底层的网络通信。提供了服务端和客户端的的操作。 DNS 模块 用于解析域名。 Domain 模块 简化异步代码的异常处理,可以捕捉处理try catch无法捕捉的。 GET/POST请求 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);// 解析 url 参数
var params = url.parse(req.url, true).query; res.write("网站名:" + params.name); res.write("\n"); res.write("网站 URL:" + params.url);获取 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> ysx 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) { 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);文件
读取 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("程序执行完毕。");// 异步打开文件
var fs = require("fs"); console.log("准备打开文件!"); fs.open('input.txt', 'r+', function(err, fd) { if (err) { return console.error(err); } console.log("文件打开成功!"); });打开文件 fs.open(path, flags[, mode], callback) path - 文件的路径。 flags - 文件打开的行为。具体值详见下文。 mode - 设置文件模式(权限),文件创建默认权限为 0666(可读,可写)。 callback - 回调函数,带有两个参数如:callback(err, fd)。 Flag 描述 r 以读取模式打开文件。如果文件不存在抛出异常。 r+ 以读写模式打开文件。如果文件不存在抛出异常。 rs 以同步的方式读取文件。 rs+ 以同步的方式读取和写入文件。 w 以写入模式打开文件,如果文件不存在则创建。 wx 类似 'w',但是如果文件路径存在,则文件写入失败。 w+ 以读写模式打开文件,如果文件不存在则创建。 wx+ 类似 'w+', 但是如果文件路径存在,则文件读写失败。 a 以追加模式打开文件,如果文件不存在则创建。 ax 类似 'a', 但是如果文件路径存在,则文件追加失败。 a+ 以读取追加模式打开文件,如果文件不存在则创建。 ax+ 类似 'a+', 但是如果文件路径存在,则文件读取追加失败。
获取文件信息
fs.stat(path, callback) path - 文件路径。 callback - 回调函数,带有两个参数如:(err, stats), stats 是 fs.Stats 对象。 Node.js 常用工具 util 是一个Node.js 核心模块,提供常用函数的集合,用于弥补核心JavaScript 的功能 过于精简的不足。 util.inherits(constructor, superConstructor)是一个实现对象间原型继承 的函数 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); Sub 仅仅继承了Base 在原型中定义的函数,而构造函数内部创造的 base 属 性和 sayHello 函数都没有被 Sub 继承 util.isArray(object) //"object" 是一个数组返回true,否则返回false util.isRegExp(object) // "object" 是一个正则表达式返回true,否则返回false util.isDate(object) // "object" 是一个日期返回true,否则返回false util.isError(object) // "object" 是一个错误对象返回true,否则返回falseNode.js 全局对象
在最外层定义的变量; 全局对象的属性; 隐式定义的变量(未定义直接赋值的变量)// 输出全局变量 __filename 的值 __filename 表示当前正在执行的脚本的文件名
console.log(__filename); // 输出全局变量 __dirname 的值 __dirname 表示当前执行脚本所在的目录 console.log( __dirname ); setTimeout(cb, ms) clearTimeout(t); setInterval(cb, ms) clearInterval(t) Node.js 路由router1.js var http = require("http"); var url = require("url"); function start() { function onRequest(request, response) { var pathname = url.parse(request.url).pathname; console.log("Request for " + pathname + " received."); response.writeHead(200, {"Content-Type": "text/plain"}); response.write("router1 Hello ysx "); response.end(); } http.createServer(onRequest).listen(8888); console.log("Server has started."); } exports.start = start;router2.js
function router(pathname) { console.log("About to router a request for " + pathname); } exports.router = router;router3.js
var router1 = require("./router1"); var router2 = require("./router2"); router1.start(router2.router); Node.js 函数 JavaScript中,一个函数可以作为另一个函数的参数 function say(word) { console.log(word); } function execute(sameFunction, value) { sameFunction(value); } execute(say, "ysx");匿名函数 execute(function (ysx) { console.log(ysx); }, "ysx");匿名函数的http服务器工作 var http = require("http"); http.createServer(function (request, response) { response.writeHead(200, { "Content-Type": "text/plain" }); response.write("Hello ysx"); response.end(); }).listen(8888); 模块系统 var hello = require('./hello'); hello.world(); //代码 require('./hello') 引入了当前目录下的 hello.js 文件hello.js 文件,代码如下:
exports.world = function() { console.log('Hello World'); }模块引用
expres.js 文件 // exports.ysx = function(){ // console.log('hello ysx '); // } function ysx() { var name; this.setName = function (thyName) { name = thyName; }; this.sayHellow = function () { console.log("Hellow " + name); }; }; module.exports = ysx;express.js 文件引用expres.js //模块 var hello = require("./expres"); // hello.ysx(); console.log(hello); ysx = new hello(); ysx.setName("sxsx ="); ysx.sayHellow();Node.js 中自带了一个叫做 http 的模块
var http = require("http"); http.createServer(...); Node.js Stream(流) Stream 是一个抽象接口,Node 中有很多对象实现了这个接口。例如,对http 服务器发起请求的request 对象就是一个 Stream,还有stdout(标准输出)。Stream 有四种流类型: Readable - 可读操作。 Writable - 可写操作。 Duplex - 可读可写操作. Transform - 操作被写入数据,然后读出结果。所有的 Stream 对象都是 EventEmitter 的实例,事件有:
data - 当有数据可读时触发。 end - 没有更多的数据可读时触发。 error - 在接收和写入过程中发生错误时触发。 finish - 所有数据已被写入到底层系统时触发。//读取 处理流事件 --> data,end,error/默认事件 var fs = require("fs"); var datas = ""; //创建可读流 var readerStream = fs.createReadStream("input.txt"); //设置编码格式 utf-8 readerStream.setEncoding("UTF8"); //处理流事件 --> data,end,error readerStream.on("data", function (chunk) { datas += chunk; }); readerStream.on("end", function () { console.log("end " + datas); }); readerStream.on("error", function (err) { console.log("error " + err.stack); }); console.log("程序结束 ");//写入流 writerStream.write(datas, "UTF8");
var fs = require("fs"); var datas = "www.ysxsx.com"; //创建一个可以写入的流,写入到文件 var writerStream = fs.createWriteStream("input.txt"); //写入内容,编码格式 writerStream.write(datas, "UTF8"); //标记文件末尾 writerStream.end(); // //处理事件 --> data,end,error // writerStream.on("finish", function () { // console.log("finish" + " 写入完成。"); // }); // writerStream.on("error", function () { // console.log("error" + err.stack); // }); // console.log("程序执行完毕。");管道流 (处理大文件)
管道提供了一个输出流到输入流的机制。通常我们用于从一个流中获取数据并将数据传递到另外一个流中实例: var fs = require("fs"); var read = fs.createReadStream("input.txt"); var write = fs.createWriteStream("output.txt"); read.pipe(write);链式流 (压缩,多线程执行解压) 链式是通过连接输出流到另外一个流并创建多个流操作链的机制。链式流一般用于管道操作实例: 压缩 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 Buffer (缓冲区) JavaScript 语言自身只有字符串数据类型,没有二进制数据类型 在处理像TCP流或文件流时,必须使用到二进制数据。因此在 Node.js中,定义了一个 Buffer 类,该类用来创建一个专门存放二进制数据的缓存区 Buffer 类是随 Node 内核一起发布的核心库 在 Node.js 中处理I/O操作中移动的数据时,就有可能使用 Buffer 库const buf = Buffer.from("runoob", "ascii");//两种数据编码格式
console.log(buf.toString("hex")); console.log(buf.toString('base64'));Node.js 目前支持的字符编码包括: ascii - 仅支持 7 位 ASCII 数据。如果设置去掉高位的话,这种编码是非常快的。 utf8 - 多字节编码的 Unicode 字符。许多网页和其他文档格式都使用 UTF-8 。 utf16le - 2 或 4 个字节,小字节序编码的 Unicode 字符。支持代理对(U+10000 至 U+10FFFF)。 ucs2 - utf16le 的别名。 base64 - Base64 编码。 latin1 - 一种把 Buffer 编码成一字节编码的字符串的方式。 binary - latin1 的别名。 hex - 将每个字节编码为两个十六进制字符。 Buffer 提供了以下 API 来创建 Buffer 类: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 实例// 创建一个长度为 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');写入 Node 缓冲区的语法如下
buf.write(string[, offset[, length]][, encoding])参数描述如下: string - 写入缓冲区的字符串。 offset - 缓冲区开始写入的索引值,默认为 0 。 length - 写入的字节数,默认为 buffer.length encoding - 使用的编码。默认为 'utf8' 。返回值 返回实际写入的大小。如果 buffer 空间不足, 则只会写入部分字符串读取 Node 缓冲区数据的语法如下 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')); // 输出: abcdefghijklmnopqrstuvwxyz console.log( buf.toString('ascii',0,5)); // 输出: abcde console.log( buf.toString('utf8',0,5)); // 输出: abcde console.log( buf.toString(undefined,0,5)); // 使用 'utf8' 编码, 并输出: abcde 将 Node Buffer 转换为 JSON 对象的函数语法格式 buf.toJSON() 字符串化一个 Buffer 实例时,JSON.stringify() 会隐式地调用该 toJSON()实例 const buf = Buffer.from([0x1, 0x2, 0x3, 0x4, 0x5]); const json = JSON.stringify(buf);// 输出: {"type":"Buffer","data":[1,2,3,4,5]}
console.log(json);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); 缓冲区合并语法 Node 缓冲区合并的语法如下所示: Buffer.concat(list[, totalLength])参数 list - 用于合并的 Buffer 对象数组列表。 totalLength - 指定合并后Buffer对象的总长度。返回值
返回一个多个成员合并的新 Buffer 对象。实例
var buffer1 = Buffer.from(('YSX')); var buffer2 = Buffer.from(('www.YSX.com')); var buffer3 = Buffer.concat([buffer1,buffer2]); console.log("buffer3 内容: " + buffer3.toString());执行以上代码,输出结果为: buffer3 内容: YSXwww.YSX.com返回值
解码缓冲区数据并使用指定的编码返回字符串。缓冲区比较 buf.compare(otherBuffer);//otherBuffer - 与 buf 对象比较的另外一个 Buffer 对象返回值 返回一个数字,表示 buf 在 otherBuffer 之前,之后或相同eg: 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 + "之后"); }拷贝缓冲区 buf.copy(targetBuffer[, targetStart[, sourceStart[, sourceEnd]]])参数 targetBuffer - 要拷贝的 Buffer 对象。 targetStart - 数字, 可选, 默认: 0 sourceStart - 数字, 可选, 默认: 0 sourceEnd - 数字, 可选, 默认: buffer.length返回值 没有返回值。实例 拷贝插入 var buf1 = Buffer.from('abcdefghijkl'); var buf2 = Buffer.from('RUNOOB'); //将 buf2 插入到 buf1 指定位置上 abRUNOOBijkl buf2.copy(buf1, 2); console.log(buf1.toString()); 执行以上代码,输出结果为: abRUNOOBijkl缓冲区裁剪
buf.slice([start[, end]]) 参数 start - 数字, 可选, 默认: 0 end - 数字, 可选, 默认: buffer.length返回值 返回一个新的缓冲区,它和旧缓冲区指向同一块内存,但是从索引 start 到 end 的位置剪切实例 var buffer1 = Buffer.from('runoob'); // 剪切缓冲区 var buffer2 = buffer1.slice(0,2); console.log("buffer2 content: " + buffer2.toString()); 执行以上代码,输出结果为: buffer2 content: ru缓冲区长度 buf.length;Events
addListener(event, listener)为指定事件添加一个监听器到监听器数组的尾部。2 on(event, listener)为指定事件注册一个监听器,接受一个字符串 event 和一个回调函数。server.on('connection', function (stream) { console.log('someone connected!');});3 once(event, listener)为指定事件注册一个单次监听器,即 监听器最多只会触发一次,触发后立刻解除该监听器。server.once('connection', function (stream) { console.log('Ah, we have our first user!');});4 removeListener(event, listener)移除指定事件的某个监听器,监听器必须是该事件已经注册过的监听器。它接受两个参数,第一个是事件名称,第二个是回调函数名称。
var callback = function(stream) {
console.log('someone connected!');};server.on('connection', callback);// ...server.removeListener('connection', callback);5 removeAllListeners([event])移除所有事件的所有监听器, 如果指定事件,则移除指定事件的所有监听器。6 setMaxListeners(n)默认情况下, EventEmitters 如果你添加的监听器超过 10 个就会输出警告信息。 setMaxListeners 函数用于提高监听器的默认限制的数量。7 listeners(event)返回指定事件的监听器数组。8 emit(event, [arg1], [arg2], [...])按参数的顺序执行每个监听器,如果事件有注册监听返回 true,否则返回 false。类方法
events.emitter.listenerCount(eventName) //推荐事件1 newListener event - 字符串,事件名称 listener - 处理事件函数该事件在添加新监听器时被触发。
2 removeListener
event - 字符串,事件名称 listener - 处理事件函数从指定监听器数组中删除一个监听器。需要注意的是,此操作将会改变处于被删监听器之后的那些监听器的索引。
eg: var events = require("events"); var eventEmitter = new events.EventEmitter(); var listener1 = function listener1() { console.log("监听 1 ="); } var listener2 = function listener2() { console.log("监听 2 ="); } //绑定 connection 事件 处理函数 eventEmitter.addListener("connection", listener1); eventEmitter.on("connection", listener2); var eventEmitters = eventEmitter.listenerCount("connection"); console.log(eventEmitters + " 个监听器监听连接事件"); //处理conncction事件 eventEmitter.emit("connection"); //移出绑定的 listener1 函数 eventEmitter.removeListener("connection", listener1); console.log("listener1 不再受监听。"); // 触发连接事件 eventEmitter.emit('connection'); eventListeners = eventEmitter.listenerCount('connection'); console.log(eventListeners + " 个监听器监听连接事件。");事件驱动 emit on 事件绑定
EventEmitters ->Event -><- Event Loop ->Event Handleers引入 events 模块 var events = require("events");创建 eventEmitter 对象 var eventEmitter = new events.EventMitter();绑定事件处理程序: eventEmitter.on('eventName',eventHandler);通过程序触发 eventEmitter.emit("eventName");Node.js 事件循环 Node.js 是单进程单线程应用程序,V8提供的异步执行回调接口,处理大量并发,高性能 Node.js几乎每个API都支持回调函数 Node.js 基本上所有事件机制都是观察者模式实现 Node.js 单线程类似进入一个while(true)的事件循环,直到没有事件观察者退出,每个异步事件都生成一个事件观察者,如果事件发生就调用该回调函数Node.js 回调函数
node.js 异步编程的直接体现就是回调 回调函数一般作为函数的最后一个参数出现 function test1(name,age,callback1,callback2){}阻塞代码 等待读取文件完之后,继续执行之后命令 var fs = require("fs"); var data = fs.readFileSync("input.txt"); console.log("读取input.txt内容: " + data.toString());(回调)非阻塞代码 异步,无需等待读取文件,与输出各自执行 var fss = require("fs"); var datas = fss.readFile('input.txt', function (err, data) { if (err) { return console.error(err); } console.log("读取input.txt内容: " + data.toString()); });Node.js REPL(交互式解释器)
(Read Eval Print Loop:交互式解释器)表示一个电脑环境,类似Window系统终端或者Unix/Linux shell。可以再终端输入命令,接收系统的响应。启动Node终端命令:
node终端REPL 命令:REPL 命令 ctrl + c - 退出当前终端。 ctrl + c 按下两次 - 退出 Node REPL。 ctrl + d - 退出 Node REPL. 向上/向下 键 - 查看输入的历史命令 tab 键 - 列出当前命令 .help - 列出使用命令 .break - 退出多行表达式 .clear - 退出多行表达式 .save filename - 保存当前的 Node REPL 会话到指定文件 .load filename - 载入当前 Node REPL 会话的文件内容。//··如果旧版本的npm 升级
sudo npm install npm -g window 系统命令: npm install npm -g 淘宝镜像命令: cnpm install npm -g查看安装信息
npm list npm list -g #全局npm 命令安装Node.js web框架模块express:
npm install express # 本地安装 npm install express -g # 本地安装(global)如果出现以下错误: npm err! Error: connect ECONNREFUSED 127.0.0.1:8087 解决办法为: $ npm config set proxy null Node.js 三部分组成 1 引入 required模块:使用 require 指令来载入 Node.js 模块。 2 创建服务器:服务器可以监听客户端的请求,类似于Apache、Njinx、等HTTP服务器 3 接受请求与响应式请求 服务器很容易创建,客户端可以使用浏览器或终端发送Http请求,服务器接收请求后返回请求数据步骤一 引入required模块 var http = required("http");//实例化http赋值给变量http步骤二 创建服务器:服务器可以监听客户端的请求,类似于Apache、Njinx、等HTTP服务器 node test.js //执行test.js文件Node 版本,命令行:
node -v想创建自己的服务,那Node.js可以胜任
后端程序员,想部署一些高性能的服务,那么Node.js也行