Node.js Learning Notes
<h1>简介</h1><p>简单的说 Node.js 就是运行在服务端的 JavaScript。</p>
<p>Node.js 是一个基于Chrome JavaScript 运行时建立的一个平台。</p>
<p>Node.js是一个事件驱动I/O服务端JavaScript环境,基于Google的V8引擎,V8引擎执行Javascript的速度非常快,性能非常好。</p>
<h1>安装</h1>
<p>下载地址:https://nodejs.org/en/download/</p>
<div class="cnblogs_code">
<pre>wget https://nodejs.org/dist/v10.16.3/node-v10.16.3.tar.gz</pre>
</div>
<p>解压</p>
<div class="cnblogs_code">
<pre>tar -zxvf node-v10.16.3.tar.gz</pre>
</div>
<p>编译</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">sudo ./configure
sudo make
sudo make install</span></pre>
</div>
<p>查看 node 版本:</p>
<div class="cnblogs_code">
<pre>node --version</pre>
</div>
<p> 若不在环境变量中可添加软连接</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">ln -s /usr/software/nodejs/bin/npm /usr/local/bin/
ln -s /usr/software/nodejs/bin/node /usr/local/bin/</span></pre>
</div>
<h1> 使用</h1>
<p>如果我们使用PHP来编写后端的代码时,需要Apache 或者 Nginx 的HTTP 服务器,并配上 mod_php5 模块和php-cgi。</p>
<p>从这个角度看,整个"接收 HTTP 请求并提供 Web 页面"的需求根本不需 要 PHP 来处理。</p>
<p>不过对 Node.js 来说,概念完全不一样了。使用 Node.js 时,我们不仅仅 在实现一个应用,同时还实现了整个 HTTP 服务器。事实上,我们的 Web 应用以及对应的 Web 服务器基本上是一样的。</p>
<p>在我们创建 Node.js 第一个 "Hello, World!" 应用前,让我们先了解下 Node.js 应用是由哪几部分组成的:</p>
<ol>
<li>
<p><strong>引入 required 模块:</strong>我们可以使用 <strong>require</strong> 指令来载入 Node.js 模块。</p>
</li>
<li>
<p><strong>创建服务器:</strong>服务器可以监听客户端的请求,类似于 Apache 、Nginx 等 HTTP 服务器。</p>
</li>
<li>
<p><strong>接收请求与响应请求</strong> 服务器很容易创建,客户端可以使用浏览器或终端发送 HTTP 请求,服务器接收请求后返回响应数据。</p>
</li>
</ol>
<h2>创建 Node.js 应用</h2>
<h3>步骤一、引入 required 模块</h3>
<p>我们使用 <strong>require</strong> 指令来载入 http 模块,并将实例化的 HTTP 赋值给变量 http,实例如下:</p>
<div class="cnblogs_code">
<pre>var http = require("http");</pre>
</div>
<h3>步骤二、创建服务器</h3>
<p>接下来我们使用 http.createServer() 方法创建服务器,并使用 listen 方法绑定 8888 端口。 函数通过 request, response 参数来接收和响应数据。</p>
<p>实例如下,在你项目的根目录下创建一个叫 server.js 的文件,并写入以下代码:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">//引入http模块<br>var http = require('http');
//创建服务<br>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);
// 终端打印如下信息
console.log('Server running at http://127.0.0.1:8888/');</span></pre>
</div>
<p> </p>
<p>以上代码我们完成了一个可以工作的 HTTP 服务器。</p>
<p>使用 <strong>node</strong> 命令执行以上的代码:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">node server.js
Server running at http://127.0.0.1:8888/</span></pre>
</div>
<p><img src="https://img2018.cnblogs.com/blog/1399348/201910/1399348-20191003155802290-2045311125.png" alt=""></p>
<p>接下来,打开浏览器访问 http://127.0.0.1:8888/,你会看到一个写着 "Hello World"的网页。</p>
<p><img src="https://img2018.cnblogs.com/blog/1399348/201910/1399348-20191003155844220-612603624.png" alt="" width="1025" height="200"></p>
<p><strong>分析Node.js 的 HTTP 服务器:</strong></p>
<ul>
<li>第一行请求(require)Node.js 自带的 http 模块,并且把它赋值给 http 变量。</li>
<li>接下来我们调用 http 模块提供的函数: createServer 。这个函数会返回 一个对象,这个对象有一个叫做 listen 的方法,这个方法有一个数值参数, 指定这个 HTTP 服务器监听的端口号。</li>
</ul>
<h1>npm</h1>
<p>简介:</p>
<p>npm全称为Node Package Manager,是一个基于Node.js的包管理器,也是整个Node.js社区最流行、支持的第三方模块最多的包管理器。</p>
<p>npm的初衷:JavaScript开发人员更容易分享和重用代码。</p>
<p>npm的使用场景:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">允许用户从NPM服务器下载别人编写的第三方包到本地使用。
允许用户从NPM服务器下载并安装别人编写的命令行程序到本地使用。
允许用户将自己编写的包或命令行程序上传到NPM服务器供别人使用。</span></pre>
</div>
<p>npm版本查询:</p>
<div class="cnblogs_code">
<pre>npm -v </pre>
</div>
<p>npm安装:</p>
<p> 1、安装nodejs 由于新版的nodejs已经集成了npm,所以可直接通过输入npm -v来测试是否成功安装。</p>
<p> 2、使用npm命令来升级npm: npm install npm -g</p>
<p>使用淘宝镜像</p>
<div class="cnblogs_code">
<pre>npm install -g cnpm --registry=https://registry.npm.taobao.org</pre>
</div>
<div class="article-body">
<div id="content" class="article-intro">
<h2>使用 npm 命令安装模块</h2>
<p>npm 安装 Node.js 模块语法格式如下:</p>
<div class="cnblogs_code">
<pre>npm install <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">Module </span><span style="color: rgba(255, 0, 0, 1)">Name</span><span style="color: rgba(0, 0, 255, 1)">></span></pre>
</div>
<p>以下实例,我们使用 npm 命令安装常用的 Node.js web框架模块 <strong>express</strong>:</p>
<div class="cnblogs_code">
<pre>npm install express</pre>
</div>
<p>安装好之后,express 包就放在了工程目录下的 node_modules 目录中,因此在代码中只需要通过 <strong>require('express')</strong> 的方式就好,无需指定第三方包路径。</p>
<div class="cnblogs_code">
<pre>var express = require('express');</pre>
</div>
<h2>全局安装与本地安装</h2>
<p>npm 的包安装分为本地安装(local)、全局安装(global)两种,从敲的命令行来看,差别只是有没有-g而已,比如</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">npm install express # 本地安装
npm install express -g # 全局安装</span></pre>
</div>
<p>如果出现以下错误:</p>
<div class="cnblogs_code">
<pre>npm err! Error: connect ECONNREFUSED 127.0.0.1:8087</pre>
</div>
<p>解决办法为:</p>
<div class="cnblogs_code">
<pre>npm config set proxy null</pre>
</div>
<h3>本地安装</h3>
<ul>
<li>1. 将安装包放在 ./node_modules 下(运行 npm 命令时所在的目录),如果没有 node_modules 目录,会在当前执行 npm 命令的目录下生成 node_modules 目录。</li>
<li>2. 可以通过 require() 来引入本地安装的包。</li>
</ul>
<h3>全局安装</h3>
<ul>
<li>1. 将安装包放在 /usr/local 下或者你 node 的安装目录。</li>
<li>2. 可以直接在命令行里使用。</li>
</ul>
<p>如果你希望具备两者功能,则需要在两个地方安装它或使用 <strong>npm link</strong>。</p>
<p>接下来我们使用全局方式安装 express</p>
<div class="cnblogs_code">
<pre>npm install express -g</pre>
</div>
<p>安装过程输出如下内容,第一行输出了模块的版本号及安装位置。</p>
<div class="cnblogs_code"><img id="code_img_closed_3cb431fe-12a5-4452-8766-5d9f17424141" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_3cb431fe-12a5-4452-8766-5d9f17424141" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_3cb431fe-12a5-4452-8766-5d9f17424141" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 0, 1)">express@4.13.3 node_modules/express
├── escape-html@1.0.2
├── range-parser@1.0.2
├── merge-descriptors@1.0.0
├── array-flatten@1.1.1
├── cookie@0.1.3
├── utils-merge@1.0.0
├── parseurl@1.3.0
├── cookie-signature@1.0.6
├── methods@1.1.1
├── fresh@0.3.0
├── vary@1.0.1
├── path-to-regexp@0.1.7
├── content-type@1.0.1
├── etag@1.7.0
├── serve-static@1.10.0
├── content-disposition@0.5.0
├── depd@1.0.1
├── qs@4.0.0
├── finalhandler@0.4.0 (unpipe@1.0.0)
├── on-finished@2.3.0 (ee-first@1.1.1)
├── proxy-addr@1.0.8 (forwarded@0.1.0, ipaddr.js@1.0.1)
├── debug@2.2.0 (ms@0.7.1)
├── type-is@1.6.8 (media-typer@0.3.0, mime-types@2.1.6)
├── accepts@1.2.12 (negotiator@0.5.3, mime-types@2.1.6)
└── send@0.13.0 (destroy@1.0.3, statuses@1.2.1, ms@0.7.1, mime@1.3.4, http-errors@1.3.1)</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<h3>查看安装信息</h3>
<p>你可以使用以下命令来查看所有全局安装的模块:</p>
<div class="cnblogs_code">
<pre>npm list -g</pre>
</div>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">├─┬ cnpm@4.3.2
│ ├── auto-correct@1.0.0
│ ├── bagpipe@0.3.5
│ ├── colors@1.1.2
│ ├─┬ commander@2.9.0
│ │ └── graceful-readlink@1.0.1
│ ├─┬ cross-spawn@0.2.9
│ │ └── lru-cache@2.7.3</span></pre>
</div>
<p>如果要查看某个模块的版本号,可以使用命令如下:</p>
<div class="cnblogs_code">
<pre>npm list grunt</pre>
</div>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">projectName@projectVersion /path/to/project/folder
└── grunt@0.4.1</span></pre>
</div>
<h2>使用 package.json</h2>
<p>package.json 位于模块的目录下,用于定义包的属性。接下来让我们来看下 express 包的 package.json 文件,位于 node_modules/express/package.json 内容:</p>
<div class="cnblogs_code"><img id="code_img_closed_4bea08eb-d333-46ee-85a4-07fb6a6a3518" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_4bea08eb-d333-46ee-85a4-07fb6a6a3518" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_4bea08eb-d333-46ee-85a4-07fb6a6a3518" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 0, 1)">{
"name": "express",
"description": "Fast, unopinionated, minimalist web framework",
"version": "4.13.3",
"author": {
"name": "TJ Holowaychuk",
"email": "tj@vision-media.ca"
},
"contributors": [
{
"name": "Aaron Heckmann",
"email": "aaron.heckmann+github@gmail.com"
},
{
"name": "Ciaran Jessup",
"email": "ciaranj@gmail.com"
},
{
"name": "Douglas Christopher Wilson",
"email": "doug@somethingdoug.com"
},
{
"name": "Guillermo Rauch",
"email": "rauchg@gmail.com"
},
{
"name": "Jonathan Ong",
"email": "me@jongleberry.com"
},
{
"name": "Roman Shtylman",
"email": "shtylman+expressjs@gmail.com"
},
{
"name": "Young Jae Sim",
"email": "hanul@hanul.me"
}
],
"license": "MIT",
"repository": {
"type": "git",
"url": "git+https://github.com/strongloop/express.git"
},
"homepage": "http://expressjs.com/",
"keywords": [
"express",
"framework",
"sinatra",
"web",
"rest",
"restful",
"router",
"app",
"api"
],
"dependencies": {
"accepts": "~1.2.12",
"array-flatten": "1.1.1",
"content-disposition": "0.5.0",
"content-type": "~1.0.1",
"cookie": "0.1.3",
"cookie-signature": "1.0.6",
"debug": "~2.2.0",
"depd": "~1.0.1",
"escape-html": "1.0.2",
"etag": "~1.7.0",
"finalhandler": "0.4.0",
"fresh": "0.3.0",
"merge-descriptors": "1.0.0",
"methods": "~1.1.1",
"on-finished": "~2.3.0",
"parseurl": "~1.3.0",
"path-to-regexp": "0.1.7",
"proxy-addr": "~1.0.8",
"qs": "4.0.0",
"range-parser": "~1.0.2",
"send": "0.13.0",
"serve-static": "~1.10.0",
"type-is": "~1.6.6",
"utils-merge": "1.0.0",
"vary": "~1.0.1"
},
"devDependencies": {
"after": "0.8.1",
"ejs": "2.3.3",
"istanbul": "0.3.17",
"marked": "0.3.5",
"mocha": "2.2.5",
"should": "7.0.2",
"supertest": "1.0.1",
"body-parser": "~1.13.3",
"connect-redis": "~2.4.1",
"cookie-parser": "~1.3.5",
"cookie-session": "~1.2.0",
"express-session": "~1.11.3",
"jade": "~1.11.0",
"method-override": "~2.3.5",
"morgan": "~1.6.1",
"multiparty": "~4.1.2",
"vhost": "~3.0.1"
},
"engines": {
"node": ">= 0.10.0"
},
"files": [
"LICENSE",
"History.md",
"Readme.md",
"index.js",
"lib/"
],"scripts":{"test":"mocha --require test/support/env --reporter spec --bail --check-leaks test/ test/acceptance/","test-ci":"istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --require test/support/env --reporter spec --check-leaks test/ test/acceptance/","test-cov":"istanbul cover node_modules/mocha/bin/_mocha -- --require test/support/env --reporter dot --check-leaks test/ test/acceptance/","test-tap":"mocha --require test/support/env --reporter tap --check-leaks test/ test/acceptance/"},"gitHead":"ef7ad681b245fba023843ce94f6bcb8e275bbb8e","bugs":{"url":"https://github.com/strongloop/express/issues"},"_id":"express@4.13.3","_shasum":"ddb2f1fb4502bf33598d2b032b037960ca6c80a3","_from":"express@*","_npmVersion":"1.4.28","_npmUser":{"name":"dougwilson","email":"doug@somethingdoug.com"},"maintainers":[{"name":"tjholowaychuk","email":"tj@vision-media.ca"},{"name":"jongleberry","email":"jonathanrichardong@gmail.com"},{"name":"dougwilson","email":"doug@somethingdoug.com"},{"name":"rfeng","email":"enjoyjava@gmail.com"},{"name":"aredridel","email":"aredridel@dinhe.net"},{"name":"strongloop","email":"callback@strongloop.com"},{"name":"defunctzombie","email":"shtylman@gmail.com"}],"dist":{"shasum":"ddb2f1fb4502bf33598d2b032b037960ca6c80a3","tarball":"http://registry.npmjs.org/express/-/express-4.13.3.tgz"},"directories":{},"_resolved":"https://registry.npmjs.org/express/-/express-4.13.3.tgz","readme":"ERROR: No README data found!"}</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<h2 class="prettyprint prettyprinted"><span style="font-size: 1.17em; font-family: "PingFang SC", "Helvetica Neue", Helvetica, Arial, sans-serif">Package.json 属性说明</span></h2>
<ul>
<li>
<p><strong>name</strong> - 包名。</p>
</li>
<li>
<p><strong>version</strong> - 包的版本号。</p>
</li>
<li>
<p><strong>description</strong> - 包的描述。</p>
</li>
<li>
<p><strong>homepage</strong> - 包的官网 url 。</p>
</li>
<li>
<p><strong>author</strong> - 包的作者姓名。</p>
</li>
<li>
<p><strong>contributors</strong> - 包的其他贡献者姓名。</p>
</li>
<li>
<p><strong>dependencies</strong> - 依赖包列表。如果依赖包没有安装,npm 会自动将依赖包安装在 node_module 目录下。</p>
</li>
<li>
<p><strong>repository</strong> - 包代码存放的地方的类型,可以是 git 或 svn,git 可在 Github 上。</p>
</li>
<li>
<p><strong>main</strong> - main 字段指定了程序的主入口文件,require('moduleName') 就会加载这个文件。这个字段的默认值是模块根目录下面的 index.js。</p>
</li>
<li>
<p><strong>keywords</strong> - 关键字</p>
</li>
</ul>
<h2>卸载模块</h2>
<p>我们可以使用以下命令来卸载 Node.js 模块。</p>
<div class="cnblogs_code">
<pre>npm uninstall express</pre>
</div>
<p>卸载后,你可以到 /node_modules/ 目录下查看包是否还存在,或者使用以下命令查看:</p>
<div class="cnblogs_code">
<pre>npm ls</pre>
</div>
<h2>更新模块</h2>
<p>我们可以使用以下命令更新模块:</p>
<div class="cnblogs_code">
<pre>npm update express</pre>
</div>
<h2>搜索模块</h2>
<p>使用以下来搜索模块:</p>
<div class="cnblogs_code">
<pre>npm search express</pre>
</div>
<h2>创建模块</h2>
<p>创建模块,package.json 文件是必不可少的。我们可以使用 NPM 生成 package.json 文件,生成的文件包含了基本的结果。</p>
<div class="cnblogs_code"><img id="code_img_closed_96dad2e2-826f-4998-8b9b-32b430324b78" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_96dad2e2-826f-4998-8b9b-32b430324b78" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_96dad2e2-826f-4998-8b9b-32b430324b78" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 0, 1)">$ npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.
See `npm help json` for definitive documentation on these fields
and exactly what they do.
Use `npm install </span><span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">pkg</span><span style="color: rgba(0, 0, 255, 1)">></span><span style="color: rgba(0, 0, 0, 1)"> --save` afterwards to install a package and
save it as a dependency in the package.json file.
Press ^C at any time to quit.
name: (node_modules) runoob # 模块名
version: (1.0.0)
description: Node.js 测试模块(www.runoob.com)# 描述
entry point: (index.js)
test command: make test
git repository: https://github.com/runoob/runoob.git# Github 地址
keywords:
author:
license: (ISC)
About to write to ……/node_modules/package.json: # 生成地址
{
"name": "runoob",
"version": "1.0.0",
"description": "Node.js 测试模块(www.runoob.com)",
……
}
Is this ok? (yes) yes</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p>以上的信息,你需要根据你自己的情况输入。在最后输入 "yes" 后会生成 package.json 文件。</p>
<p>接下来我们可以使用以下命令在 npm 资源库中注册用户(使用邮箱注册):</p>
<div class="cnblogs_code">
<pre>npm adduser</pre>
</div>
<pre class="prettyprint prettyprinted"><span class="pln"><span class="typ">Username<span class="pun">:<span class="pln"> mcmohd
<span class="typ">Password<span class="pun">:<span class="pln">
<span class="typ">Email<span class="pun">:<span class="pln"> <span class="pun">(<span class="kwd">this<span class="pln"> IS <span class="kwd">public<span class="pun">)<span class="pln"> mcmohd@gmail<span class="pun">.<span class="pln">com</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></pre>
<p>接下来我们就用以下命令来发布模块:</p>
<div class="cnblogs_code">
<pre>npm publish</pre>
</div>
<p>如果你以上的步骤都操作正确,你就可以跟其他模块一样使用 npm 来安装。</p>
<h2>版本号</h2>
<p>使用NPM下载和发布代码时都会接触到版本号。NPM使用语义版本号来管理代码,这里简单介绍一下。</p>
<p>语义版本号分为X.Y.Z三位,分别代表主版本号、次版本号和补丁版本号。当代码变更时,版本号按以下原则更新。</p>
<ul>
<li>如果只是修复bug,需要更新Z位。</li>
<li>如果是新增了功能,但是向下兼容,需要更新Y位。</li>
<li>如果有大变动,向下不兼容,需要更新X位。</li>
</ul>
<p>版本号有了这个保证后,在申明第三方包依赖时,除了可依赖于一个固定版本号外,还可依赖于某个范围的版本号。例如"argv": "0.0.x"表示依赖于0.0.x系列的最新版argv。</p>
<p>NPM支持的所有版本号范围指定方式可以查看官方文档。</p>
<h2>NPM 常用命令</h2>
<p>除了本章介绍的部分外,NPM还提供了很多功能,package.json里也有很多其它有用的字段。</p>
<p>除了可以在npmjs.org/doc/查看官方文档外,这里再介绍一些NPM常用命令。</p>
<p>NPM提供了很多命令,例如install和publish,使用npm help可查看所有命令。</p>
<ul>
<li>
<p>NPM提供了很多命令,例如<code>install</code>和<code>publish</code>,使用<code>npm help</code>可查看所有命令。</p>
</li>
<li>
<p>使用<code>npm help <command></code>可查看某条命令的详细帮助,例如<code>npm help install</code>。</p>
</li>
<li>
<p>在<code>package.json</code>所在目录下使用<code>npm install . -g</code>可先在本地安装当前命令行程序,可用于发布前的本地测试。</p>
</li>
<li>
<p>使用<code>npm update <package></code>可以把当前目录下<code>node_modules</code>子目录里边的对应模块更新至最新版本。</p>
</li>
<li>
<p>使用<code>npm update <package> -g</code>可以把全局安装的对应命令行程序更新至最新版。</p>
</li>
<li>
<p>使用<code>npm cache clear</code>可以清空NPM本地缓存,用于对付使用相同版本号发布新版本代码的人。</p>
</li>
<li>
<p>使用<code>npm unpublish <package>@<version></code>可以撤销发布自己发布过的某个版本代码。</p>
</li>
</ul>
<h2 id="taobaonpm">使用淘宝 NPM 镜像</h2>
<p>大家都知道国内直接使用 npm 的官方镜像是非常慢的,这里推荐使用淘宝 NPM 镜像。</p>
<p>淘宝 NPM 镜像是一个完整 npmjs.org 镜像,你可以用此代替官方版本(只读),同步频率目前为 10分钟 一次以保证尽量与官方服务同步。</p>
<p>你可以使用淘宝定制的 cnpm (gzip 压缩支持) 命令行工具代替默认的 npm:</p>
<div class="cnblogs_code">
<pre>npm install -g cnpm --registry=https://registry.npm.taobao.org</pre>
</div>
<p>这样就可以使用 cnpm 命令来安装模块了:</p>
<div class="cnblogs_code">
<pre>cnpm install </pre>
</div>
<p>更多信息可以查阅:http://npm.taobao.org/。</p>
</div>
</div>
<div id="postcomments"><ol class="commentlist">
<li id="comment-42953" class="comment even thread-even depth-1">
<div id="div-comment-42953" class="comt-main">
<p data-title="npm resource busy or locked 解决方法">如果你遇到了使用 npm 安 装node_modules 总是提示报错:报错:<strong> npm resource busy or locked.....</strong>。</p>
<p>可以先删除以前安装的 node_modules :</p>
</div>
</li>
</ol></div>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">npm cache clean
npm install</span></pre>
</div>
<h1>Node.js REPL(交互式解释器)</h1>
<p>Node.js REPL(Read Eval Print Loop:交互式解释器) 表示一个电脑的环境,类似 Window 系统的终端或 Unix/Linux shell,我们可以在终端中输入命令,并接收系统的响应。</p>
<p>Node 自带了交互式解释器,可以执行以下任务:</p>
<ul>
<li>
<p><strong>读取</strong> - 读取用户输入,解析输入了Javascript 数据结构并存储在内存中。</p>
</li>
<li>
<p><strong>执行</strong> - 执行输入的数据结构</p>
</li>
<li>
<p><strong>打印</strong> - 输出结果</p>
</li>
<li>
<p><strong>循环</strong> - 循环操作以上步骤直到用户两次按下 <strong>ctrl-c</strong> 按钮退出。</p>
</li>
</ul>
<p>Node 的交互式解释器可以很好的调试 Javascript 代码。</p>
<p>开始学习 REPL</p>
<p>我们可以输入以下命令来启动 Node 的终端:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">$ node
></span></pre>
</div>
<p>这时我们就可以在 > 后输入简单的表达式,并按下回车键来计算结果。</p>
<h3>简单的表达式运算</h3>
<p>接下来让我们在 Node.js REPL 的命令行窗口中执行简单的数学运算:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">$ node
> 1 +4
5
> 5 / 2
2.5
> 3 * 6
18
> 4 - 1
3
> 1 + ( 2 * 3 ) - 4
3
></span></pre>
</div>
<h3>使用变量</h3>
<p>你可以将数据存储在变量中,并在你需要的时候使用它。</p>
<p>变量声明需要使用 <strong>var</strong> 关键字,如果没有使用 var 关键字变量会直接打印出来。</p>
<p>使用 <strong>var</strong> 关键字的变量可以使用 console.log() 来输出变量。</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">$ node
> x = 10
10
> var y = 10
undefined
> x + y
20
> console.log("Hello World")
Hello World
undefined
> console.log("www.runoob.com")
www.runoob.com
undefined</span></pre>
</div>
<h3>多行表达式</h3>
<p>Node REPL 支持输入多行表达式,这就有点类似 JavaScript。接下来让我们来执行一个 do-while 循环:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">$ node
> var x = 0
undefined
> do {
... x++;
... console.log("x: " + x);
... } while ( x </span><span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)"> 5 </span><span style="color: rgba(255, 0, 0, 1)">);
x: 1
x: 2
x: 3
x: 4
x: 5
undefined
</span><span style="color: rgba(0, 0, 255, 1)">></span></pre>
</div>
<p><strong>...</strong> 三个点的符号是系统自动生成的,你回车换行后即可。Node 会自动检测是否为连续的表达式。</p>
<h3>下划线(_)变量</h3>
<p>你可以使用下划线(_)获取上一个表达式的运算结果:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">$ node
> var x = 10
undefined
> var y = 20
undefined
> x + y
30
> var sum = _
undefined
> console.log(sum)
30
undefined
></span></pre>
</div>
<h2>REPL 命令</h2>
<ul>
<li>
<p><strong>ctrl + c</strong> - 退出当前终端。</p>
</li>
<li>
<p><strong>ctrl + c 按下两次</strong> - 退出 Node REPL。</p>
</li>
<li>
<p><strong>ctrl + d</strong> - 退出 Node REPL.</p>
</li>
<li>
<p><strong>向上/向下 键</strong> - 查看输入的历史命令</p>
</li>
<li>
<p><strong>tab 键</strong> - 列出当前命令</p>
</li>
<li>
<p><strong>.help</strong> - 列出使用命令</p>
</li>
<li>
<p><strong>.break</strong> - 退出多行表达式</p>
</li>
<li>
<p><strong>.clear</strong> - 退出多行表达式</p>
</li>
<li>
<p><strong>.save <em>filename</em></strong> - 保存当前的 Node REPL 会话到指定文件</p>
</li>
<li>
<p><strong>.load <em>filename</em></strong> - 载入当前 Node REPL 会话的文件内容。</p>
</li>
</ul>
<h2>停止 REPL</h2>
<p>前面我们已经提到按下两次 <strong>ctrl + c</strong> 键就能退出 REPL:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">$ node
>
(^C again to quit)
></span></pre>
</div>
<h1>Node.js 回调函数</h1>
<p>Node.js <span style="font-size: 18pt"><strong>异步编程</strong></span>的直接体现就是回调。</p>
<p>异步编程依托于回调来实现,但不能说使用了回调后程序就异步化了。</p>
<p>回调函数在完成任务后就会被调用,Node 使用了大量的回调函数,Node 所有 API 都支持回调函数。</p>
<p>例如,我们可以一边读取文件,一边执行其他命令,在文件读取完成后,我们将文件内容作为回调函数的参数返回。这样在执行代码时就没有阻塞或等待文件 I/O 操作。这就大大提高了 Node.js 的性能,可以处理大量的并发请求。</p>
<p>回调函数一般作为函数的最后一个参数出现:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">function foo1(name, age, callback) { }
function foo2(value, callback1, callback2) { }</span></pre>
</div>
<p> </p>
<h2>阻塞代码实例</h2>
<p>创建一个文件 input.txt ,内容如下:</p>
<div class="cnblogs_code">
<pre>blocking demo test text</pre>
</div>
<p> </p>
<p>创建 main.js 文件, 代码如下:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">var fs = require('fs');
var data = fs.readFileSync('input.txt');
console.log(data.toString())
console.log("程序执行完毕")</span></pre>
</div>
<p> </p>
<p>以上代码执行结果如下:</p>
<p><img src="https://img2018.cnblogs.com/blog/1399348/201910/1399348-20191003165629429-573500732.png" alt=""></p>
<h2>非阻塞代码实例</h2>
<p>创建一个文件 input.txt ,内容如下:</p>
<div class="cnblogs_code">
<pre>no blocking demo test text</pre>
</div>
<p> </p>
<p>创建 main.js 文件, 代码如下:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> fs = require('fs'<span style="color: rgba(0, 0, 0, 1)">);
fs.readFile(</span>'input.txt', <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> (err, data) {
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (err) <span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> console.error(err)
console.log(data.toString())
})
console.log(</span>"程序执行完毕") </pre>
</div>
<p>以上代码执行结果如下:</p>
<p><img src="https://img2018.cnblogs.com/blog/1399348/201910/1399348-20191003170019771-2056722914.png" alt=""></p>
<p>以上两个实例我们了解了阻塞与非阻塞调用的不同。第一个实例在文件读取完后才执行完程序。 第二个实例我们不需要等待文件读取完,这样就可以在读取文件时同时执行接下来的代码,大大提高了程序的性能。</p>
<p>因此,阻塞是按顺序执行的,而非阻塞是不需要按顺序的,所以如果需要处理回调函数的参数,我们就需要写在回调函数内。</p>
<h1>Node.js 事件循环</h1>
<p>Node.js 是<span style="font-size: 18pt"><strong>单进程单线程应用程序</strong></span>,但是因为 V8 引擎提供的异步执行回调接口,通过这些接口可以处理大量的并发,所以性能非常高。</p>
<p>Node.js 几乎每一个 API 都是支持回调函数的。</p>
<p>Node.js 基本上所有的事件机制都是用设计模式中<span style="font-size: 18pt"><strong>观察者模式</strong></span>实现。</p>
<p>Node.js <span style="color: rgba(255, 0, 0, 1); font-size: 14pt"><strong>单线程类似进入一个while(true)的事件循环,直到没有事件观察者退出,每个异步事件都生成一个事件观察者,如果有事件发生就调用该回调函数.</strong></span></p>
<h2>事件驱动程序</h2>
<p>Node.js 使用事件驱动模型,当web server接收到请求,就把它关闭然后进行处理,然后去服务下一个web请求。</p>
<p>当这个请求完成,它被放回处理队列,当到达队列开头,这个结果被返回给用户。</p>
<p>这个模型非常高效可扩展性非常强,因为webserver一直接受请求而不等待任何读写操作。(这也被称之为非阻塞式IO或者事件驱动IO)</p>
<p>在事件驱动模型中,会生成一个主循环来监听事件,当检测到事件时触发回调函数。</p>
<p> </p>
<p><img src="https://www.runoob.com/wp-content/uploads/2015/09/event_loop.jpg" alt=""></p>
<p>整个事件驱动的流程就是这么实现的,非常简洁。有点类似于观察者模式,事件相当于一个主题(Subject),而所有注册到这个事件上的处理函数相当于观察者(Observer)。</p>
<p>Node.js 有多个内置的事件,我们可以通过引入 events 模块,并通过实例化 EventEmitter 类来绑定和监听事件,如下实例:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 引入 events 模块</span>
<span style="color: rgba(0, 0, 255, 1)">var</span> events = require('events'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 创建 eventEmitter 对象</span>
<span style="color: rgba(0, 0, 255, 1)">var</span> eventEmitter = <span style="color: rgba(0, 0, 255, 1)">new</span> events.EventEmitter();</pre>
</div>
<p> </p>
<p>以下程序绑定事件处理程序:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 绑定事件及事件的处理程序</span>
eventEmitter.on('eventName', eventHandler);</pre>
</div>
<p> </p>
<p>我们可以通过程序触发事件:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 触发事件</span>
eventEmitter.emit('eventName');</pre>
</div>
<p> </p>
<h3>实例</h3>
<p>创建 main.js 文件,代码如下所示:</p>
<div class="cnblogs_code"><img id="code_img_closed_de1a6d8c-9aa1-40cd-8f65-14bc524474ae" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_de1a6d8c-9aa1-40cd-8f65-14bc524474ae" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_de1a6d8c-9aa1-40cd-8f65-14bc524474ae" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 引入 events 模块</span>
<span style="color: rgba(0, 0, 255, 1)">var</span> events = require('events'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 创建 eventEmitter 对象</span>
<span style="color: rgba(0, 0, 255, 1)">var</span> eventEmitter = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> events.EventEmitter();
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 创建事件处理程序</span>
<span style="color: rgba(0, 0, 255, 1)">var</span> connectHandler = <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> connected() {
console.log(</span>'连接成功。'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 触发 data_received 事件 </span>
eventEmitter.emit('data_received'<span style="color: rgba(0, 0, 0, 1)">);
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 绑定 connection 事件处理程序</span>
eventEmitter.on('connection'<span style="color: rgba(0, 0, 0, 1)">, connectHandler);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 使用匿名函数绑定 data_received 事件</span>
eventEmitter.on('data_received', <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(){
console.log(</span>'数据接收成功。'<span style="color: rgba(0, 0, 0, 1)">);
});
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 触发 connection 事件 </span>
eventEmitter.emit('connection'<span style="color: rgba(0, 0, 0, 1)">);
console.log(</span>"程序执行完毕。");</pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p>接下来让我们执行以上代码:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">$ node main.js
连接成功。
数据接收成功。
程序执行完毕。</span></pre>
</div>
<p> </p>
<h2>Node 应用程序是如何工作的?</h2>
<p>在 Node 应用程序中,执行异步操作的函数将回调函数作为最后一个参数, 回调函数接收错误对象作为第一个参数。</p>
<p>接下来让我们来重新看下前面的实例,创建一个 input.txt ,文件内容如下:</p>
<div class="cnblogs_code">
<pre>no blocking demo test text</pre>
</div>
<p> </p>
<p>创建 main.js 文件,代码如下:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> fs = require("fs"<span style="color: rgba(0, 0, 0, 1)">);
fs.readFile(</span>'input.txt', <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> (err, data) {
</span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (err){
console.log(err.stack);
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)">;
}
console.log(data.toString());
});
console.log(</span>"程序执行完毕");</pre>
</div>
<p> </p>
<p>以上程序中 fs.readFile() 是异步函数用于读取文件。 如果在读取文件过程中发生错误,错误 err 对象就会输出错误信息。</p>
<p>如果没发生错误,readFile 跳过 err 对象的输出,文件内容就通过回调函数输出。</p>
<p>执行以上代码,执行结果如下:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">程序执行完毕
no blocking demo test text</span> </pre>
</div>
<p>接下来我们删除 input.txt 文件,执行结果如下所示:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">程序执行完毕
Error: ENOENT, open </span>'input.txt'</pre>
</div>
<p> </p>
<p>因为文件 input.txt 不存在,所以输出了错误信息。</p>
<h1>Node.js EventEmitter</h1>
<p>Node.js 所有的异步 I/O 操作在完成时都会发送一个事件到事件队列。</p>
<p>Node.js 里面的许多对象都会分发事件:一个 net.Server 对象会在每次有新连接时触发一个事件, 一个 fs.readStream 对象会在文件被打开的时候触发一个事件。 所有这些产生事件的对象都是 events.EventEmitter 的实例。</p>
<h2>EventEmitter 类</h2>
<p>events 模块只提供了一个对象: events.EventEmitter。EventEmitter 的核心就是事件触发与事件监听器功能的封装。</p>
<p>你可以通过require("events");来访问该模块。</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 引入 events 模块</span>
<span style="color: rgba(0, 0, 255, 1)">var</span> events = require('events'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 创建 eventEmitter 对象</span>
<span style="color: rgba(0, 0, 255, 1)">var</span> eventEmitter = <span style="color: rgba(0, 0, 255, 1)">new</span> events.EventEmitter();</pre>
</div>
<p> </p>
<p>EventEmitter 对象如果在实例化时发生错误,会触发 error 事件。当添加新的监听器时,newListener 事件会触发,当监听器被移除时,removeListener 事件被触发。</p>
<p>下面我们用一个简单的例子说明 EventEmitter 的用法:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">event.js 文件</span>
<span style="color: rgba(0, 0, 255, 1)">var</span> EventEmitter = require('events'<span style="color: rgba(0, 0, 0, 1)">).EventEmitter;
</span><span style="color: rgba(0, 0, 255, 1)">var</span> event = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> EventEmitter();
event.on(</span>'some_event', <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">() {
console.log(</span>'some_event 事件触发'<span style="color: rgba(0, 0, 0, 1)">);
});
setTimeout(</span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">() {
event.emit(</span>'some_event'<span style="color: rgba(0, 0, 0, 1)">);
}, </span>1000);</pre>
</div>
<p> </p>
<p>执行结果如下:</p>
<p>运行这段代码,1 秒后控制台输出了 <strong>'some_event 事件触发'</strong>。其原理是 event 对象注册了事件 some_event 的一个监听器,然后我们通过 setTimeout 在 1000 毫秒以后向 event 对象发送事件 some_event,此时会调用some_event 的监听器。</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">$ node event.js
some_event 事件触发</span></pre>
</div>
<p> </p>
<p>EventEmitter 的每个事件由一个事件名和若干个参数组成,事件名是一个字符串,通常表达一定的语义。对于每个事件,EventEmitter 支持 若干个事件监听器。</p>
<p>当事件触发时,注册到这个事件的事件监听器被依次调用,事件参数作为回调函数参数传递。</p>
<p>让我们以下面的例子解释这个过程:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">event.js 文件</span>
<span style="color: rgba(0, 0, 255, 1)">var</span> events = require('events'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> emitter = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> events.EventEmitter();
emitter.on(</span>'someEvent', <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(arg1, arg2) {
console.log(</span>'listener1'<span style="color: rgba(0, 0, 0, 1)">, arg1, arg2);
});
emitter.on(</span>'someEvent', <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(arg1, arg2) {
console.log(</span>'listener2'<span style="color: rgba(0, 0, 0, 1)">, arg1, arg2);
});
emitter.emit(</span>'someEvent', 'arg1 参数', 'arg2 参数');</pre>
</div>
<p> </p>
<p>执行以上代码,运行的结果如下:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">$ node event.js
listener1 arg1 参数 arg2 参数
listener2 arg1 参数 arg2 参数</span></pre>
</div>
<p> </p>
<p>以上例子中,emitter 为事件 someEvent 注册了两个事件监听器,然后触发了 someEvent 事件。</p>
<p>运行结果中可以看到两个事件监听器回调函数被先后调用。 这就是EventEmitter最简单的用法。</p>
<p>EventEmitter 提供了多个属性,如 <strong>on</strong> 和 <strong>emit</strong>。<strong>on</strong> 函数用于绑定事件函数,<strong>emit</strong> 属性用于触发一个事件。接下来我们来具体看下 EventEmitter 的属性介绍。</p>
<h3>方法</h3>
<table class="reference">
<tbody>
<tr><th>序号</th><th>方法 & 描述</th></tr>
<tr>
<td>1</td>
<td><strong>addListener(event, listener)</strong><br>为指定事件添加一个监听器到监听器数组的尾部。</td>
</tr>
<tr>
<td>2</td>
<td><strong>on(event, listener)</strong><br>为指定事件注册一个监听器,接受一个字符串 event 和一个回调函数。
<pre class="prettyprint prettyprinted"><span class="pln">server<span class="pun">.<span class="pln">on<span class="pun">(<span class="str">'connection'<span class="pun">,<span class="pln"> <span class="kwd">function<span class="pln"> <span class="pun">(<span class="pln">stream<span class="pun">)<span class="pln"> <span class="pun">{<span class="pln">
console<span class="pun">.<span class="pln">log<span class="pun">(<span class="str">'someone connected!'<span class="pun">);<span class="pln">
<span class="pun">});</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></pre>
</td>
</tr>
<tr>
<td>3</td>
<td><strong>once(event, listener)</strong><br>为指定事件注册一个单次监听器,即 监听器最多只会触发一次,触发后立刻解除该监听器。
<pre class="prettyprint prettyprinted"><span class="pln">server<span class="pun">.<span class="pln">once<span class="pun">(<span class="str">'connection'<span class="pun">,<span class="pln"> <span class="kwd">function<span class="pln"> <span class="pun">(<span class="pln">stream<span class="pun">)<span class="pln"> <span class="pun">{<span class="pln">
console<span class="pun">.<span class="pln">log<span class="pun">(<span class="str">'Ah, we have our first user!'<span class="pun">);<span class="pln">
<span class="pun">});</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></pre>
</td>
</tr>
<tr>
<td>4</td>
<td><strong>removeListener(event, listener)</strong><br>
<p>移除指定事件的某个监听器,监听器必须是该事件已经注册过的监听器。</p>
<p>它接受两个参数,第一个是事件名称,第二个是回调函数名称。</p>
<pre class="prettyprint prettyprinted"><span class="kwd">var<span class="pln"> callback <span class="pun">=<span class="pln"> <span class="kwd">function<span class="pun">(<span class="pln">stream<span class="pun">)<span class="pln"> <span class="pun">{<span class="pln">
console<span class="pun">.<span class="pln">log<span class="pun">(<span class="str">'someone connected!'<span class="pun">);<span class="pln">
<span class="pun">};<span class="pln">
server<span class="pun">.<span class="pln">on<span class="pun">(<span class="str">'connection'<span class="pun">,<span class="pln"> callback<span class="pun">);<span class="pln">
<span class="com">// ...<span class="pln">
server<span class="pun">.<span class="pln">removeListener<span class="pun">(<span class="str">'connection'<span class="pun">,<span class="pln"> callback<span class="pun">);</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></pre>
</td>
</tr>
<tr>
<td>5</td>
<td><strong>removeAllListeners()</strong><br>移除所有事件的所有监听器, 如果指定事件,则移除指定事件的所有监听器。</td>
</tr>
<tr>
<td>6</td>
<td><strong>setMaxListeners(n)</strong><br>默认情况下, EventEmitters 如果你添加的监听器超过 10 个就会输出警告信息。 setMaxListeners 函数用于提高监听器的默认限制的数量。</td>
</tr>
<tr>
<td>7</td>
<td><strong>listeners(event)</strong><br>返回指定事件的监听器数组。</td>
</tr>
<tr>
<td>8</td>
<td><strong>emit(event, , , [...])</strong><br>按监听器的顺序执行执行每个监听器,如果事件有注册监听返回 true,否则返回 false。</td>
</tr>
</tbody>
</table>
<h3>类方法</h3>
<table class="reference">
<tbody>
<tr><th>序号</th><th>方法 & 描述</th></tr>
<tr>
<td>1</td>
<td><strong>listenerCount(emitter, event)</strong><br>返回指定事件的监听器数量。</td>
</tr>
</tbody>
</table>
<pre class="prettyprint prettyprinted"><span class="pln">events<span class="pun">.<span class="typ">EventEmitter<span class="pun">.<span class="pln">listenerCount<span class="pun">(<span class="pln">emitter<span class="pun">,<span class="pln"> eventName<span class="pun">)<span class="pln"> <span class="com">//已废弃,不推荐<span class="pln">
events<span class="pun">.<span class="pln">emitter<span class="pun">.<span class="pln">listenerCount<span class="pun">(<span class="pln">eventName<span class="pun">)<span class="pln"> <span class="com">//推荐</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></pre>
<h3>事件</h3>
<table class="reference">
<tbody>
<tr><th>序号</th><th>事件 & 描述</th></tr>
<tr>
<td>1</td>
<td><strong>newListener</strong><br>
<ul>
<li>
<p><strong>event</strong> - 字符串,事件名称</p>
</li>
<li>
<p><strong>listener</strong> - 处理事件函数</p>
</li>
</ul>
<p>该事件在添加新监听器时被触发。</p>
</td>
</tr>
<tr>
<td>2</td>
<td><strong>removeListener</strong><br>
<ul>
<li>
<p><strong>event</strong> - 字符串,事件名称</p>
</li>
<li>
<p><strong>listener</strong> - 处理事件函数</p>
</li>
</ul>
<p>从指定监听器数组中删除一个监听器。需要注意的是,此操作将会改变处于被删监听器之后的那些监听器的索引。</p>
</td>
</tr>
</tbody>
</table>
<h3>实例</h3>
<p>以下实例通过 connection(连接)事件演示了 EventEmitter 类的应用。</p>
<p>创建 main.js 文件,代码如下:</p>
<div class="cnblogs_code"><img id="code_img_closed_70942bc3-506e-4396-8b41-faf6a34d9cf6" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_70942bc3-506e-4396-8b41-faf6a34d9cf6" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_70942bc3-506e-4396-8b41-faf6a34d9cf6" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> events = require('events'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> eventEmitter = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> events.EventEmitter();
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 监听器 #1</span>
<span style="color: rgba(0, 0, 255, 1)">var</span> listener1 = <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> listener1() {
console.log(</span>'监听器 listener1 执行。'<span style="color: rgba(0, 0, 0, 1)">);
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 监听器 #2</span>
<span style="color: rgba(0, 0, 255, 1)">var</span> listener2 = <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> listener2() {
console.log(</span>'监听器 listener2 执行。'<span style="color: rgba(0, 0, 0, 1)">);
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 绑定 connection 事件,处理函数为 listener1 </span>
eventEmitter.addListener('connection'<span style="color: rgba(0, 0, 0, 1)">, listener1);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 绑定 connection 事件,处理函数为 listener2</span>
eventEmitter.on('connection'<span style="color: rgba(0, 0, 0, 1)">, listener2);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> eventListeners = eventEmitter.listenerCount('connection'<span style="color: rgba(0, 0, 0, 1)">);
console.log(eventListeners </span>+ " 个监听器监听连接事件。"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 处理 connection 事件 </span>
eventEmitter.emit('connection'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 移除监绑定的 listener1 函数</span>
eventEmitter.removeListener('connection'<span style="color: rgba(0, 0, 0, 1)">, listener1);
console.log(</span>"listener1 不再受监听。"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 触发连接事件</span>
eventEmitter.emit('connection'<span style="color: rgba(0, 0, 0, 1)">);
eventListeners </span>= eventEmitter.listenerCount('connection'<span style="color: rgba(0, 0, 0, 1)">);
console.log(eventListeners </span>+ " 个监听器监听连接事件。"<span style="color: rgba(0, 0, 0, 1)">);
console.log(</span>"程序执行完毕。");</pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p>以上代码,执行结果如下所示:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">$ node main.js
</span>2<span style="color: rgba(0, 0, 0, 1)"> 个监听器监听连接事件。
监听器 listener1 执行。
监听器 listener2 执行。
listener1 不再受监听。
监听器 listener2 执行。
</span>1<span style="color: rgba(0, 0, 0, 1)"> 个监听器监听连接事件。
程序执行完毕。</span></pre>
</div>
<h2>error 事件</h2>
<p>EventEmitter 定义了一个特殊的事件 error,它包含了错误的语义,我们在遇到 异常的时候通常会触发 error 事件。</p>
<p>当 error 被触发时,EventEmitter 规定如果没有响 应的监听器,Node.js 会把它当作异常,退出程序并输出错误信息。</p>
<p>我们一般要为会触发 error 事件的对象设置监听器,避免遇到错误后整个程序崩溃。例如:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> events = require('events'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> emitter = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> events.EventEmitter();
emitter.emit(</span>'error');</pre>
</div>
<p>运行时会显示以下错误:</p>
<div class="cnblogs_code">
<pre>node.js:201
<span style="color: rgba(0, 0, 255, 1)">throw</span> e; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> process.nextTick error, or 'error' event on first tick </span>
^<span style="color: rgba(0, 0, 0, 1)">
Error: Uncaught, unspecified </span>'error'<span style="color: rgba(0, 0, 0, 1)"> event.
at EventEmitter.emit (events.js:</span>50:15<span style="color: rgba(0, 0, 0, 1)">)
at Object.</span><anonymous> (/home/byvoid/error.js:5:9)
at Module._compile (module.js:441:26<span style="color: rgba(0, 0, 0, 1)">)
at Object..js (module.js:</span>459:10<span style="color: rgba(0, 0, 0, 1)">)
at Module.load (module.js:</span>348:31<span style="color: rgba(0, 0, 0, 1)">)
at Function._load (module.js:</span>308:12<span style="color: rgba(0, 0, 0, 1)">)
at Array.</span>0 (module.js:479:10<span style="color: rgba(0, 0, 0, 1)">)
at EventEmitter._tickCallback (node.js:</span>192:40)</pre>
</div>
<h2>继承 EventEmitter</h2>
<p>大多数时候我们不会直接使用 EventEmitter,而是在对象中继承它。包括 fs、net、 http 在内的,只要是支持事件响应的核心模块都是 EventEmitter 的子类。</p>
<p>为什么要这样做呢?原因有两点:</p>
<p>首先,具有某个实体功能的对象实现事件符合语义, 事件的监听和发生应该是一个对象的方法。</p>
<p>其次 JavaScript 的对象机制是基于原型的,支持 部分多重继承,继承 EventEmitter 不会打乱对象原有的继承关系。</p>
<div class="article-body">
<div class="article-intro"> </div>
<div class="article-intro"> </div>
<div class="article-intro"> </div>
<div class="article-intro"> </div>
<div class="article-intro"> </div>
<div class="article-intro"> </div>
<div class="article-intro"> </div>
<div class="article-intro"> </div>
<div class="article-intro"> </div>
<div id="content" class="article-intro">
<h1>Node.js Buffer(缓冲区)</h1>
<p>JavaScript 语言自身只有字符串数据类型,没有二进制数据类型。</p>
<p>但在处理像TCP流或文件流时,必须使用到二进制数据。因此在 Node.js中,定义了一个 Buffer 类,该类用来创建一个专门存放二进制数据的缓存区。</p>
<p>在 Node.js 中,Buffer 类是随 Node 内核一起发布的核心库。Buffer 库为 Node.js 带来了一种存储原始数据的方法,可以让 Node.js 处理二进制数据,每当需要在 Node.js 中处理I/O操作中移动的数据时,就有可能使用 Buffer 库。原始数据存储在 Buffer 类的实例中。一个 Buffer 类似于一个整数数组,但它对应于 V8 堆内存之外的一块原始内存。</p>
<blockquote>
<p>在v6.0之前创建Buffer对象直接使用new Buffer()构造函数来创建对象实例,但是Buffer对内存的权限操作相比很大,可以直接捕获一些敏感信息,所以在v6.0以后,官方文档里面建议使用 <span class="marked">Buffer.from() 接口去创建Buffer对象。</span></p>
</blockquote>
<hr>
<h2>Buffer 与字符编码</h2>
<p>Buffer 实例一般用于表示编码字符的序列,比如 UTF-8 、 UCS2 、 Base64 、或十六进制编码的数据。 通过使用显式的字符编码,就可以在 Buffer 实例与普通的 JavaScript 字符串之间进行相互转换。</p>
<div class="cnblogs_code">
<pre>const buf = Buffer.from('hello','ascii'<span style="color: rgba(0, 0, 0, 1)">);
console.log(buf.toString(</span>'hex'))<br>//输出:68656c6c6f</pre>
</div>
<div class="cnblogs_code">
<pre>console.log(buf.toString('base64'<span style="color: rgba(0, 0, 0, 1)">));
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 输出 aGVsbG8=</span> </pre>
</div>
<p><strong>Node.js 目前支持的字符编码包括:</strong></p>
<ul>
<li>
<p><strong>ascii</strong> - 仅支持 7 位 ASCII 数据。如果设置去掉高位的话,这种编码是非常快的。</p>
</li>
<li>
<p><strong>utf8</strong> - 多字节编码的 Unicode 字符。许多网页和其他文档格式都使用 UTF-8 。</p>
</li>
<li>
<p><strong>utf16le</strong> - 2 或 4 个字节,小字节序编码的 Unicode 字符。支持代理对(U+10000 至 U+10FFFF)。</p>
</li>
<li>
<p><strong>ucs2</strong> - <strong>utf16le</strong> 的别名。</p>
</li>
<li>
<p><strong>base64</strong> - Base64 编码。</p>
</li>
<li>
<p><strong>latin1</strong> - 一种把 <strong>Buffer</strong> 编码成一字节编码的字符串的方式。</p>
</li>
<li>
<p><strong>binary</strong> - <strong>latin1</strong> 的别名。</p>
</li>
<li>
<p><strong>hex</strong> - 将每个字节编码为两个十六进制字符。</p>
</li>
</ul>
<h2>创建 Buffer 类</h2>
<p>Buffer 提供了以下 API 来创建 Buffer 类:</p>
<ul>
<li><strong>Buffer.alloc(size[, fill[, encoding]]):</strong> 返回一个指定大小的 Buffer 实例,如果没有设置 fill,则默认填满 0</li>
<li><strong>Buffer.allocUnsafe(size):</strong> 返回一个指定大小的 Buffer 实例,但是它不会被初始化,所以它可能包含敏感的数据</li>
<li><strong>Buffer.allocUnsafeSlow(size)</strong></li>
<li><strong>Buffer.from(array):</strong> 返回一个被 array 的值初始化的新的 Buffer 实例(传入的 array 的元素只能是数字,不然就会自动被 0 覆盖)</li>
<li><strong>Buffer.from(arrayBuffer[, byteOffset[, length]]):</strong> 返回一个新建的与给定的 ArrayBuffer 共享同一内存的 Buffer。</li>
<li><strong>Buffer.from(buffer):</strong> 复制传入的 Buffer 实例的数据,并返回一个新的 Buffer 实例</li>
<li><strong>Buffer.from(string[, encoding]):</strong> 返回一个被 string 的值初始化的新的 Buffer 实例</li>
</ul>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 创建一个长度为 10、且用 0 填充的 Buffer。</span>
const buf1 = Buffer.alloc(10<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 创建一个长度为 10、且用 0x1 填充的 Buffer。 </span>
const buf2 = Buffer.alloc(10, 1<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 创建一个长度为 10、且未初始化的 Buffer。</span><span style="color: rgba(0, 128, 0, 1)">
//</span><span style="color: rgba(0, 128, 0, 1)"> 这个方法比调用 Buffer.alloc() 更快,</span><span style="color: rgba(0, 128, 0, 1)">
//</span><span style="color: rgba(0, 128, 0, 1)"> 但返回的 Buffer 实例可能包含旧数据,</span><span style="color: rgba(0, 128, 0, 1)">
//</span><span style="color: rgba(0, 128, 0, 1)"> 因此需要使用 fill() 或 write() 重写。</span>
const buf3 = Buffer.allocUnsafe(10<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 创建一个包含 的 Buffer。</span>
const buf4 = Buffer.from();
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 创建一个包含 UTF-8 字节 的 Buffer。</span>
const buf5 = Buffer.from('tést'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 创建一个包含 Latin-1 字节 的 Buffer。</span>
const buf6 = Buffer.from('tést', 'latin1');</pre>
</div>
<h2>写入缓冲区</h2>
<h3>语法</h3>
<p>写入 Node 缓冲区的语法如下所示:</p>
<div class="cnblogs_code">
<pre>buf.write(string[, offset[, length]][, encoding])</pre>
</div>
<h3>参数</h3>
<p>参数描述如下:</p>
<ul>
<li>
<p><strong>string</strong> - 写入缓冲区的字符串。</p>
</li>
<li>
<p><strong>offset</strong> - 缓冲区开始写入的索引值,默认为 0 。</p>
</li>
<li>
<p><strong>length</strong> - 写入的字节数,默认为 buffer.length</p>
</li>
<li>
<p><strong>encoding</strong> - 使用的编码。默认为 'utf8' 。</p>
</li>
</ul>
<p>根据 encoding 的字符编码写入 string 到 buf 中的 offset 位置。 length 参数是写入的字节数。 如果 buf 没有足够的空间保存整个字符串,则只会写入 string 的一部分。 只部分解码的字符不会被写入。</p>
<h3>返回值</h3>
<p>返回实际写入的大小。如果 buffer 空间不足, 则只会写入部分字符串。</p>
<h3>实例</h3>
<div class="cnblogs_code">
<pre>buf = Buffer.alloc(256<span style="color: rgba(0, 0, 0, 1)">);
len </span>= buf.write("www.runoob.com"<span style="color: rgba(0, 0, 0, 1)">);
console.log(</span>"写入字节数 : "+len);</pre>
</div>
<p>执行以上代码,输出结果为:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">$node main.js
写入字节数 : </span>14</pre>
</div>
<p> </p>
<h2>从缓冲区读取数据</h2>
<h3>语法</h3>
<p>读取 Node 缓冲区数据的语法如下所示:</p>
<div class="cnblogs_code">
<pre>buf.toString(]])</pre>
</div>
<h3>参数</h3>
<p>参数描述如下:</p>
<ul>
<li>
<p><strong>encoding</strong> - 使用的编码。默认为 'utf8' 。</p>
</li>
<li>
<p><strong>start</strong> - 指定开始读取的索引位置,默认为 0。</p>
</li>
<li>
<p><strong>end</strong> - 结束位置,默认为缓冲区的末尾。</p>
</li>
</ul>
<h3>返回值</h3>
<p>解码缓冲区数据并使用指定的编码返回字符串。</p>
<h3>实例</h3>
<div class="cnblogs_code">
<pre>buf = Buffer.alloc(26<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">for</span> (<span style="color: rgba(0, 0, 255, 1)">var</span> i = 0 ; i < 26 ; i++<span style="color: rgba(0, 0, 0, 1)">) {
buf </span>= i + 97<span style="color: rgba(0, 0, 0, 1)">;
}
console.log( buf.toString(</span>'ascii')); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 输出: abcdefghijklmnopqrstuvwxyz</span>
console.log( buf.toString('ascii',0,5)); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 输出: abcde</span>
console.log( buf.toString('utf8',0,5)); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 输出: abcde</span>
console.log( buf.toString(undefined,0,5)); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 使用 'utf8' 编码, 并输出: abcde</span></pre>
</div>
<p>执行以上代码,输出结果为:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">$ node main.js
abcdefghijklmnopqrstuvwxyz
abcde
abcde
abcde</span></pre>
</div>
<h2>将 Buffer 转换为 JSON 对象</h2>
<h3>语法</h3>
<p>将 Node Buffer 转换为 JSON 对象的函数语法格式如下:</p>
<div class="cnblogs_code">
<pre>buf.toJSON()</pre>
</div>
<p> </p>
<p>当字符串化一个 Buffer 实例时,JSON.stringify() 会隐式地调用该 <span class="marked">toJSON()。</span></p>
<h3>返回值</h3>
<p>返回 JSON 对象。</p>
<h3>实例</h3>
<div class="cnblogs_code">
<pre>const buf = Buffer.from();
const json </span>=<span style="color: rgba(0, 0, 0, 1)"> JSON.stringify(buf);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 输出: {"type":"Buffer","data":}</span>
<span style="color: rgba(0, 0, 0, 1)">console.log(json);
const copy </span>= JSON.parse(json, (key, value) =><span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 0, 255, 1)">return</span> value && value.type === 'Buffer' ?<span style="color: rgba(0, 0, 0, 1)">
Buffer.from(value.data) :
value;
});
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 输出: <Buffer 01 02 03 04 05></span>
console.log(copy);</pre>
</div>
<p> </p>
<p>执行以上代码,输出结果为:</p>
<div class="cnblogs_code">
<pre>{"type":"Buffer","data":}
</span><Buffer 01 02 03 04 05></pre>
</div>
<h2>缓冲区合并</h2>
<h3>语法</h3>
<p>Node 缓冲区合并的语法如下所示:</p>
<div class="cnblogs_code">
<pre>Buffer.concat(list[, totalLength])</pre>
</div>
<h3>参数</h3>
<p>参数描述如下:</p>
<ul>
<li>
<p><strong>list</strong> - 用于合并的 Buffer 对象数组列表。</p>
</li>
<li>
<p><strong>totalLength</strong> - 指定合并后Buffer对象的总长度。</p>
</li>
</ul>
<h3>返回值</h3>
<p>返回一个多个成员合并的新 Buffer 对象。</p>
<h3>实例</h3>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> buffer1 = Buffer.from(('菜鸟教程'<span style="color: rgba(0, 0, 0, 1)">));
</span><span style="color: rgba(0, 0, 255, 1)">var</span> buffer2 = Buffer.from(('www.runoob.com'<span style="color: rgba(0, 0, 0, 1)">));
</span><span style="color: rgba(0, 0, 255, 1)">var</span> buffer3 =<span style="color: rgba(0, 0, 0, 1)"> Buffer.concat();
console.log(</span>"buffer3 内容: " + buffer3.toString());</pre>
</div>
<p> </p>
<p>执行以上代码,输出结果为:</p>
<pre class="prettyprint prettyprinted"><span class="pln">buffer3 <span class="pun">内容:<span class="pln"> <span class="pun">菜鸟教程<span class="pln">www<span class="pun">.<span class="pln">runoob<span class="pun">.<span class="pln">com</span></span></span></span></span></span></span></span></span></pre>
<h2>缓冲区比较</h2>
<h3>语法</h3>
<p>Node Buffer 比较的函数语法如下所示, 该方法在 Node.js v0.12.2 版本引入:</p>
<div class="cnblogs_code">
<pre>buf.compare(otherBuffer);</pre>
</div>
<p> </p>
<h3>参数</h3>
<p>参数描述如下:</p>
<ul>
<li>
<p><strong>otherBuffer</strong> - 与 <strong>buf</strong> 对象比较的另外一个 Buffer 对象。</p>
</li>
</ul>
<h3>返回值</h3>
<p>返回一个数字,表示 <strong>buf</strong> 在 <strong>otherBuffer</strong> 之前,之后或相同。</p>
<h3>实例</h3>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> buffer1 = Buffer.from('ABC'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> buffer2 = Buffer.from('ABCD'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> result =<span style="color: rgba(0, 0, 0, 1)"> buffer1.compare(buffer2);
</span><span style="color: rgba(0, 0, 255, 1)">if</span>(result < 0<span style="color: rgba(0, 0, 0, 1)">) {
console.log(buffer1 </span>+ " 在 " + buffer2 + "之前"<span style="color: rgba(0, 0, 0, 1)">);
}</span><span style="color: rgba(0, 0, 255, 1)">else</span> <span style="color: rgba(0, 0, 255, 1)">if</span>(result == 0<span style="color: rgba(0, 0, 0, 1)">){
console.log(buffer1 </span>+ " 与 " + buffer2 + "相同"<span style="color: rgba(0, 0, 0, 1)">);
}</span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)"> {
console.log(buffer1 </span>+ " 在 " + buffer2 + "之后"<span style="color: rgba(0, 0, 0, 1)">);
}</span></pre>
</div>
<p> </p>
<p>执行以上代码,输出结果为:</p>
<div class="cnblogs_code">
<pre>ABC在ABCD之前</pre>
</div>
<p> </p>
<h2>拷贝缓冲区</h2>
<h3>语法</h3>
<p>Node 缓冲区拷贝语法如下所示:</p>
<div class="cnblogs_code">
<pre>buf.copy(targetBuffer[, targetStart[, sourceStart[, sourceEnd]]])</pre>
</div>
<p> </p>
<h3>参数</h3>
<p>参数描述如下:</p>
<ul>
<li>
<p><strong>targetBuffer</strong> - 要拷贝的 Buffer 对象。</p>
</li>
<li>
<p><strong>targetStart</strong> - 数字, 可选, 默认: 0</p>
</li>
<li>
<p><strong>sourceStart</strong> - 数字, 可选, 默认: 0</p>
</li>
<li>
<p><strong>sourceEnd</strong> - 数字, 可选, 默认: buffer.length</p>
</li>
</ul>
<h3>返回值</h3>
<p>没有返回值。</p>
<h3>实例</h3>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> buf1 = Buffer.from('abcdefghijkl'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> buf2 = Buffer.from('RUNOOB'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">将 buf2 插入到 buf1 指定位置上</span>
buf2.copy(buf1, 2<span style="color: rgba(0, 0, 0, 1)">);
console.log(buf1.toString());</span></pre>
</div>
<p> </p>
<p>执行以上代码,输出结果为:</p>
<div class="cnblogs_code">
<pre>abRUNOOBijkl</pre>
</div>
<h2>缓冲区裁剪</h2>
<p>Node 缓冲区裁剪语法如下所示:</p>
<div class="cnblogs_code">
<pre>buf.slice(])</pre>
</div>
<h3>参数</h3>
<p>参数描述如下:</p>
<ul>
<li>
<p><strong>start</strong> - 数字, 可选, 默认: 0</p>
</li>
<li>
<p><strong>end</strong> - 数字, 可选, 默认: buffer.length</p>
</li>
</ul>
<h3>返回值</h3>
<p>返回一个新的缓冲区,它和旧缓冲区指向同一块内存,但是从索引 start 到 end 的位置剪切。</p>
<h3>实例</h3>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> buffer1 = Buffer.from('runoob'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 剪切缓冲区</span>
<span style="color: rgba(0, 0, 255, 1)">var</span> buffer2 = buffer1.slice(0,2<span style="color: rgba(0, 0, 0, 1)">);
console.log(</span>"buffer2 content: " + buffer2.toString());</pre>
</div>
<p> </p>
<p>执行以上代码,输出结果为:</p>
<div class="cnblogs_code">
<pre>buffer2 content: ru</pre>
</div>
<p> </p>
<h2>缓冲区长度</h2>
<h3>语法</h3>
<p>Node 缓冲区长度计算语法如下所示:</p>
<div class="cnblogs_code">
<pre>buf.length;</pre>
</div>
<p> </p>
<h3>返回值</h3>
<p>返回 Buffer 对象所占据的内存长度。</p>
<h3>实例</h3>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> buffer = Buffer.from('www.runoob.com'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">缓冲区长度</span>
console.log("buffer length: " + buffer.length);</pre>
</div>
<p> </p>
<p>执行以上代码,输出结果为:</p>
<div class="cnblogs_code">
<pre>buffer length: 14</pre>
</div>
<p> </p>
<hr>
<h2>方法参考手册</h2>
<p>以下列出了 Node.js Buffer 模块常用的方法(注意有些方法在旧版本是没有的):</p>
<table class="reference">
<tbody>
<tr><th>序号</th><th>方法 & 描述</th></tr>
<tr>
<td>1</td>
<td><strong>new Buffer(size)</strong><br>分配一个新的 size 大小单位为8位字节的 buffer。 注意, size 必须小于 kMaxLength,否则,将会抛出异常 RangeError。<span class="deprecated">废弃的: 使用 Buffer.alloc() 代替(或 Buffer.allocUnsafe())。</span></td>
</tr>
<tr>
<td>2</td>
<td><strong>new Buffer(buffer)</strong><br>拷贝参数 buffer 的数据到 Buffer 实例。<span class="deprecated">废弃的: 使用 Buffer.from(buffer) 代替。</span></td>
</tr>
<tr>
<td>3</td>
<td><strong>new Buffer(str[, encoding])</strong><br>分配一个新的 buffer ,其中包含着传入的 str 字符串。 encoding 编码方式默认为 'utf8'。 <span class="deprecated">废弃的: 使用 Buffer.from(string[, encoding]) 代替。</span></td>
</tr>
<tr>
<td>4</td>
<td><strong>buf.length</strong><br>返回这个 buffer 的 bytes 数。注意这未必是 buffer 里面内容的大小。length 是 buffer 对象所分配的内存数,它不会随着这个 buffer 对象内容的改变而改变。</td>
</tr>
<tr>
<td>5</td>
<td><strong>buf.write(string[, offset[, length]][, encoding])</strong><br>根据参数 offset 偏移量和指定的 encoding 编码方式,将参数 string 数据写入buffer。 offset 偏移量默认值是 0, encoding 编码方式默认是 utf8。 length 长度是将要写入的字符串的 bytes 大小。 返回 number 类型,表示写入了多少 8 位字节流。如果 buffer 没有足够的空间来放整个 string,它将只会只写入部分字符串。 length 默认是 buffer.length - offset。 这个方法不会出现写入部分字符。</td>
</tr>
<tr>
<td>6</td>
<td><strong>buf.writeUIntLE(value, offset, byteLength[, noAssert])</strong><br>将 value 写入到 buffer 里, 它由 offset 和 byteLength 决定,最高支持 48 位无符号整数,小端对齐,例如:<br>
<pre class="prettyprint prettyprinted"><span class="kwd">const<span class="pln"> buf <span class="pun">=<span class="pln"> <span class="typ">Buffer<span class="pun">.<span class="pln">allocUnsafe<span class="pun">(<span class="lit">6<span class="pun">);<span class="pln">
buf<span class="pun">.<span class="pln">writeUIntLE<span class="pun">(<span class="lit">0x1234567890ab<span class="pun">,<span class="pln"> <span class="lit">0<span class="pun">,<span class="pln"> <span class="lit">6<span class="pun">);<span class="pln">
<span class="com">// 输出: <Buffer ab 90 78 56 34 12><span class="pln">
console<span class="pun">.<span class="pln">log<span class="pun">(<span class="pln">buf<span class="pun">);</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></pre>
noAssert 值为 true 时,不再验证 value 和 offset 的有效性。 默认是 false。</td>
</tr>
<tr>
<td>7</td>
<td><strong>buf.writeUIntBE(value, offset, byteLength[, noAssert])</strong><br>将 value 写入到 buffer 里, 它由 offset 和 byteLength 决定,最高支持 48 位无符号整数,大端对齐。noAssert 值为 true 时,不再验证 value 和 offset 的有效性。 默认是 false。
<pre class="prettyprint prettyprinted"><span class="kwd">const<span class="pln"> buf <span class="pun">=<span class="pln"> <span class="typ">Buffer<span class="pun">.<span class="pln">allocUnsafe<span class="pun">(<span class="lit">6<span class="pun">);<span class="pln">
buf<span class="pun">.<span class="pln">writeUIntBE<span class="pun">(<span class="lit">0x1234567890ab<span class="pun">,<span class="pln"> <span class="lit">0<span class="pun">,<span class="pln"> <span class="lit">6<span class="pun">);<span class="pln">
<span class="com">// 输出: <Buffer 12 34 56 78 90 ab><span class="pln">
console<span class="pun">.<span class="pln">log<span class="pun">(<span class="pln">buf<span class="pun">);</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></pre>
</td>
</tr>
<tr>
<td>8</td>
<td><strong>buf.writeIntLE(value, offset, byteLength[, noAssert])</strong><br>将value 写入到 buffer 里, 它由offset 和 byteLength 决定,最高支持48位有符号整数,小端对齐。noAssert 值为 true 时,不再验证 value 和 offset 的有效性。 默认是 false。</td>
</tr>
<tr>
<td>9</td>
<td><strong>buf.writeIntBE(value, offset, byteLength[, noAssert])</strong><br>将value 写入到 buffer 里, 它由offset 和 byteLength 决定,最高支持48位有符号整数,大端对齐。noAssert 值为 true 时,不再验证 value 和 offset 的有效性。 默认是 false。</td>
</tr>
<tr>
<td>10</td>
<td><strong>buf.readUIntLE(offset, byteLength[, noAssert])</strong><br>支持读取 48 位以下的无符号数字,小端对齐。noAssert 值为 true 时, offset 不再验证是否超过 buffer 的长度,默认为 false。</td>
</tr>
<tr>
<td>11</td>
<td><strong>buf.readUIntBE(offset, byteLength[, noAssert])</strong><br>支持读取 48 位以下的无符号数字,大端对齐。noAssert 值为 true 时, offset 不再验证是否超过 buffer 的长度,默认为 false。</td>
</tr>
<tr>
<td>12</td>
<td><strong>buf.readIntLE(offset, byteLength[, noAssert])</strong><br>支持读取 48 位以下的有符号数字,小端对齐。noAssert 值为 true 时, offset 不再验证是否超过 buffer 的长度,默认为 false。</td>
</tr>
<tr>
<td>13</td>
<td><strong>buf.readIntBE(offset, byteLength[, noAssert])</strong><br>支持读取 48 位以下的有符号数字,大端对齐。noAssert 值为 true 时, offset 不再验证是否超过 buffer 的长度,默认为 false。</td>
</tr>
<tr>
<td>14</td>
<td><strong>buf.toString(]])</strong><br>根据 encoding 参数(默认是 'utf8')返回一个解码过的 string 类型。还会根据传入的参数 start (默认是 0) 和 end (默认是 buffer.length)作为取值范围。</td>
</tr>
<tr>
<td>15</td>
<td><strong>buf.toJSON()</strong><br>将 Buffer 实例转换为 JSON 对象。</td>
</tr>
<tr>
<td>16</td>
<td><strong>buf</strong><br>获取或设置指定的字节。返回值代表一个字节,所以返回值的合法范围是十六进制0x00到0xFF 或者十进制0至 255。</td>
</tr>
<tr>
<td>17</td>
<td><strong>buf.equals(otherBuffer)</strong><br>比较两个缓冲区是否相等,如果是返回 true,否则返回 false。</td>
</tr>
<tr>
<td>18</td>
<td><strong>buf.compare(otherBuffer)</strong><br>比较两个 Buffer 对象,返回一个数字,表示 buf 在 otherBuffer 之前,之后或相同。</td>
</tr>
<tr>
<td>19</td>
<td><strong>buf.copy(targetBuffer[, targetStart[, sourceStart[, sourceEnd]]])</strong><br>buffer 拷贝,源和目标可以相同。 targetStart 目标开始偏移和 sourceStart 源开始偏移默认都是 0。 sourceEnd 源结束位置偏移默认是源的长度 buffer.length 。</td>
</tr>
<tr>
<td>20</td>
<td><strong>buf.slice(])</strong><br>剪切 Buffer 对象,根据 start(默认是 0 ) 和 end (默认是 buffer.length ) 偏移和裁剪了索引。 负的索引是从 buffer 尾部开始计算的。</td>
</tr>
<tr>
<td>21</td>
<td><strong>buf.readUInt8(offset[, noAssert])</strong><br>根据指定的偏移量,读取一个无符号 8 位整数。若参数 noAssert 为 true 将不会验证 offset 偏移量参数。 如果这样 offset 可能会超出buffer 的末尾。默认是 false。</td>
</tr>
<tr>
<td>22</td>
<td><strong>buf.readUInt16LE(offset[, noAssert])</strong><br>根据指定的偏移量,使用特殊的 endian 字节序格式读取一个无符号 16 位整数。若参数 noAssert 为 true 将不会验证 offset 偏移量参数。 这意味着 offset 可能会超出 buffer 的末尾。默认是 false。</td>
</tr>
<tr>
<td>23</td>
<td><strong>buf.readUInt16BE(offset[, noAssert])</strong><br>根据指定的偏移量,使用特殊的 endian 字节序格式读取一个无符号 16 位整数,大端对齐。若参数 noAssert 为 true 将不会验证 offset 偏移量参数。 这意味着 offset 可能会超出 buffer 的末尾。默认是 false。</td>
</tr>
<tr>
<td>24</td>
<td><strong>buf.readUInt32LE(offset[, noAssert])</strong><br>根据指定的偏移量,使用指定的 endian 字节序格式读取一个无符号 32 位整数,小端对齐。 若参数 noAssert 为 true 将不会验证 offset 偏移量参数。 这意味着 offset 可能会超出buffer 的末尾。默认是 false。</td>
</tr>
<tr>
<td>25</td>
<td><strong>buf.readUInt32BE(offset[, noAssert])</strong><br>根据指定的偏移量,使用指定的 endian 字节序格式读取一个无符号 32 位整数,大端对齐。 若参数 noAssert 为 true 将不会验证 offset 偏移量参数。 这意味着 offset 可能会超出buffer 的末尾。默认是 false。</td>
</tr>
<tr>
<td>26</td>
<td><strong>buf.readInt8(offset[, noAssert])</strong><br>根据指定的偏移量,读取一个有符号 8 位整数。 若参数 noAssert 为 true 将不会验证 offset 偏移量参数。 这意味着 offset 可能会超出 buffer 的末尾。默认是 false。</td>
</tr>
<tr>
<td>27</td>
<td><strong>buf.readInt16LE(offset[, noAssert])</strong><br>根据指定的偏移量,使用特殊的 endian 格式读取一个 有符号 16 位整数,小端对齐。 若参数 noAssert 为 true 将不会验证 offset 偏移量参数。 这意味着 offset 可能会超出 buffer 的末尾。默认是 false。</td>
</tr>
<tr>
<td>28</td>
<td><strong>buf.readInt16BE(offset[, noAssert])</strong><br>根据指定的偏移量,使用特殊的 endian 格式读取一个 有符号 16 位整数,大端对齐。 若参数 noAssert 为 true 将不会验证 offset 偏移量参数。 这意味着 offset 可能会超出 buffer 的末尾。默认是 false。</td>
</tr>
<tr>
<td>29</td>
<td><strong>buf.readInt32LE(offset[, noAssert])</strong><br>根据指定的偏移量,使用指定的 endian 字节序格式读取一个有符号 32 位整数,小端对齐。 若参数 noAssert 为 true 将不会验证 offset 偏移量参数。 这意味着 offset 可能会超出buffer 的末尾。默认是 false。</td>
</tr>
<tr>
<td>30</td>
<td><strong>buf.readInt32BE(offset[, noAssert])</strong><br>根据指定的偏移量,使用指定的 endian 字节序格式读取一个有符号 32 位整数,大端对齐。 若参数 noAssert 为 true 将不会验证 offset 偏移量参数。 这意味着 offset 可能会超出buffer 的末尾。默认是 false。</td>
</tr>
<tr>
<td>31</td>
<td><strong>buf.readFloatLE(offset[, noAssert])</strong><br>根据指定的偏移量,使用指定的 endian 字节序格式读取一个 32 位双浮点数,小端对齐。 若参数 noAssert 为 true 将不会验证 offset 偏移量参数。 这意味着 offset 可能会超出buffer的末尾。默认是 false。</td>
</tr>
<tr>
<td>32</td>
<td><strong>buf.readFloatBE(offset[, noAssert])</strong><br>根据指定的偏移量,使用指定的 endian 字节序格式读取一个 32 位双浮点数,大端对齐。 若参数 noAssert 为 true 将不会验证 offset 偏移量参数。 这意味着 offset 可能会超出buffer的末尾。默认是 false。</td>
</tr>
<tr>
<td>33</td>
<td><strong>buf.readDoubleLE(offset[, noAssert])</strong><br>根据指定的偏移量,使用指定的 endian字节序格式读取一个 64 位双精度数,小端对齐。 若参数 noAssert 为 true 将不会验证 offset 偏移量参数。 这意味着 offset 可能会超出buffer 的末尾。默认是 false。</td>
</tr>
<tr>
<td>34</td>
<td><strong>buf.readDoubleBE(offset[, noAssert])</strong><br>根据指定的偏移量,使用指定的 endian字节序格式读取一个 64 位双精度数,大端对齐。 若参数 noAssert 为 true 将不会验证 offset 偏移量参数。 这意味着 offset 可能会超出buffer 的末尾。默认是 false。</td>
</tr>
<tr>
<td>35</td>
<td><strong>buf.writeUInt8(value, offset[, noAssert])</strong><br>根据传入的 offset 偏移量将 value 写入 buffer。注意:value 必须是一个合法的无符号 8 位整数。 若参数 noAssert 为 true 将不会验证 offset 偏移量参数。 这意味着 value 可能过大,或者 offset 可能会超出 buffer 的末尾从而造成 value 被丢弃。 除非你对这个参数非常有把握,否则不要使用。默认是 false。</td>
</tr>
<tr>
<td>36</td>
<td><strong>buf.writeUInt16LE(value, offset[, noAssert])</strong><br>根据传入的 offset 偏移量和指定的 endian 格式将 value 写入 buffer。注意:value 必须是一个合法的无符号 16 位整数,小端对齐。 若参数 noAssert 为 true 将不会验证 value 和 offset 偏移量参数。 这意味着 value 可能过大,或者 offset 可能会超出buffer的末尾从而造成 value 被丢弃。 除非你对这个参数非常有把握,否则尽量不要使用。默认是 false。</td>
</tr>
<tr>
<td>37</td>
<td><strong>buf.writeUInt16BE(value, offset[, noAssert])</strong><br>根据传入的 offset 偏移量和指定的 endian 格式将 value 写入 buffer。注意:value 必须是一个合法的无符号 16 位整数,大端对齐。 若参数 noAssert 为 true 将不会验证 value 和 offset 偏移量参数。 这意味着 value 可能过大,或者 offset 可能会超出buffer的末尾从而造成 value 被丢弃。 除非你对这个参数非常有把握,否则尽量不要使用。默认是 false。</td>
</tr>
<tr>
<td>38</td>
<td><strong>buf.writeUInt32LE(value, offset[, noAssert])</strong><br>根据传入的 offset 偏移量和指定的 endian 格式(LITTLE-ENDIAN:小字节序)将 value 写入buffer。注意:value 必须是一个合法的无符号 32 位整数,小端对齐。 若参数 noAssert 为 true 将不会验证 value 和 offset 偏移量参数。 这意味着value 可能过大,或者offset可能会超出buffer的末尾从而造成 value 被丢弃。 除非你对这个参数非常有把握,否则尽量不要使用。默认是 false。</td>
</tr>
<tr>
<td>39</td>
<td><strong>buf.writeUInt32BE(value, offset[, noAssert])</strong><br>根据传入的 offset 偏移量和指定的 endian 格式(Big-Endian:大字节序)将 value 写入buffer。注意:value 必须是一个合法的有符号 32 位整数。 若参数 noAssert 为 true 将不会验证 value 和 offset 偏移量参数。 这意味着 value 可能过大,或者offset可能会超出buffer的末尾从而造成 value 被丢弃。 除非你对这个参数非常有把握,否则尽量不要使用。默认是 false。</td>
</tr>
<tr>
<td>40</td>
<td><strong>buf.writeInt8(value, offset[, noAssert])</strong><br根据传入的 offset="" 偏移量将="" value="" 写入="" buffer="" 。注意:value="" 必须是一个合法的="" signed="" 8="" 位整数。="" 若参数="" noassert="" 为="" true="" 将不会验证="" 和="" 偏移量参数。="" 这意味着="" 可能过大,或者="" 可能会超出="" 的末尾从而造成="" 被丢弃。="" 除非你对这个参数非常有把握,否则尽量不要使用。默认是="" false。<="" td=""></td>
</tr>
<tr>
<td>41</td>
<td><strong>buf.writeInt16LE(value, offset[, noAssert])</strong><br>根据传入的 offset 偏移量和指定的 endian 格式将 value 写入 buffer。注意:value 必须是一个合法的 signed 16 位整数。 若参数 noAssert 为 true 将不会验证 value 和 offset 偏移量参数。 这意味着 value 可能过大,或者 offset 可能会超出 buffer 的末尾从而造成 value 被丢弃。 除非你对这个参数非常有把握,否则尽量不要使用。默认是 false 。</td>
</tr>
<tr>
<td>42</td>
<td><strong>buf.writeInt16BE(value, offset[, noAssert])</strong><br>根据传入的 offset 偏移量和指定的 endian 格式将 value 写入 buffer。注意:value 必须是一个合法的 signed 16 位整数。 若参数 noAssert 为 true 将不会验证 value 和 offset 偏移量参数。 这意味着 value 可能过大,或者 offset 可能会超出 buffer 的末尾从而造成 value 被丢弃。 除非你对这个参数非常有把握,否则尽量不要使用。默认是 false 。</td>
</tr>
<tr>
<td>43</td>
<td><strong>buf.writeInt32LE(value, offset[, noAssert])</strong><br>根据传入的 offset 偏移量和指定的 endian 格式将 value 写入 buffer。注意:value 必须是一个合法的 signed 32 位整数。 若参数 noAssert 为 true 将不会验证 value 和 offset 偏移量参数。 这意味着 value 可能过大,或者 offset 可能会超出 buffer 的末尾从而造成 value 被丢弃。 除非你对这个参数非常有把握,否则尽量不要使用。默认是 false。</td>
</tr>
<tr>
<td>44</td>
<td><strong>buf.writeInt32BE(value, offset[, noAssert])</strong><br>根据传入的 offset 偏移量和指定的 endian 格式将 value 写入 buffer。注意:value 必须是一个合法的 signed 32 位整数。 若参数 noAssert 为 true 将不会验证 value 和 offset 偏移量参数。 这意味着 value 可能过大,或者 offset 可能会超出 buffer 的末尾从而造成 value 被丢弃。 除非你对这个参数非常有把握,否则尽量不要使用。默认是 false。</td>
</tr>
<tr>
<td>45</td>
<td><strong>buf.writeFloatLE(value, offset[, noAssert])</strong><br>根据传入的 offset 偏移量和指定的 endian 格式将 value 写入 buffer 。注意:当 value 不是一个 32 位浮点数类型的值时,结果将是不确定的。 若参数 noAssert 为 true 将不会验证 value 和 offset 偏移量参数。 这意味着 value可能过大,或者 offset 可能会超出 buffer 的末尾从而造成 value 被丢弃。 除非你对这个参数非常有把握,否则尽量不要使用。默认是 false。</td>
</tr>
<tr>
<td>46</td>
<td><strong>buf.writeFloatBE(value, offset[, noAssert])</strong><br>根据传入的 offset 偏移量和指定的 endian 格式将 value 写入 buffer 。注意:当 value 不是一个 32 位浮点数类型的值时,结果将是不确定的。 若参数 noAssert 为 true 将不会验证 value 和 offset 偏移量参数。 这意味着 value可能过大,或者 offset 可能会超出 buffer 的末尾从而造成 value 被丢弃。 除非你对这个参数非常有把握,否则尽量不要使用。默认是 false。</td>
</tr>
<tr>
<td>47</td>
<td><strong>buf.writeDoubleLE(value, offset[, noAssert])</strong><br>根据传入的 offset 偏移量和指定的 endian 格式将 value 写入 buffer。注意:value 必须是一个有效的 64 位double 类型的值。 若参数 noAssert 为 true 将不会验证 value 和 offset 偏移量参数。 这意味着 value 可能过大,或者 offset 可能会超出 buffer 的末尾从而造成value被丢弃。 除非你对这个参数非常有把握,否则尽量不要使用。默认是 false。</td>
</tr>
<tr>
<td>48</td>
<td><strong>buf.writeDoubleBE(value, offset[, noAssert])</strong><br>根据传入的 offset 偏移量和指定的 endian 格式将 value 写入 buffer。注意:value 必须是一个有效的 64 位double 类型的值。 若参数 noAssert 为 true 将不会验证 value 和 offset 偏移量参数。 这意味着 value 可能过大,或者 offset 可能会超出 buffer 的末尾从而造成value被丢弃。 除非你对这个参数非常有把握,否则尽量不要使用。默认是 false。</td>
</tr>
<tr>
<td>49</td>
<td><strong>buf.fill(value[, offset][, end])</strong><br>使用指定的 value 来填充这个 buffer。如果没有指定 offset (默认是 0) 并且 end (默认是 buffer.length) ,将会填充整个buffer。</td>
</tr>
</tbody>
</table>
</div>
</div>
<h1>Node.js Stream(流)</h1>
<p>Stream 是一个抽象接口,Node 中有很多对象实现了这个接口。例如,对http 服务器发起请求的request 对象就是一个 Stream,还有stdout(标准输出)。</p>
<p>Node.js,Stream 有四种流类型:</p>
<ul>
<li>
<p><strong>Readable</strong> - 可读操作。</p>
</li>
<li>
<p><strong>Writable</strong> - 可写操作。</p>
</li>
<li>
<p><strong>Duplex</strong> - 可读可写操作.</p>
</li>
<li>
<p><strong>Transform</strong> - 操作被写入数据,然后读出结果。</p>
</li>
</ul>
<p>所有的 Stream 对象都是 EventEmitter 的实例。常用的事件有:</p>
<ul>
<li>
<p><strong>data</strong> - 当有数据可读时触发。</p>
</li>
<li>
<p><strong>end</strong> - 没有更多的数据可读时触发。</p>
</li>
<li>
<p><strong>error</strong> - 在接收和写入过程中发生错误时触发。</p>
</li>
<li>
<p><strong>finish</strong> - 所有数据已被写入到底层系统时触发。</p>
</li>
</ul>
<p>本教程会为大家介绍常用的流操作。</p>
<h2>从流中读取数据</h2>
<p>创建 input.txt 文件,内容如下:</p>
<div class="cnblogs_code">
<pre>mikey </pre>
</div>
<p>创建 main.js 文件, 代码如下:</p>
<div class="cnblogs_code"><img id="code_img_closed_7dceebd6-4cb7-40a3-9ec9-4ca71c990163" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_7dceebd6-4cb7-40a3-9ec9-4ca71c990163" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_7dceebd6-4cb7-40a3-9ec9-4ca71c990163" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> fs = require("fs"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> data = ''<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 创建可读流</span>
<span style="color: rgba(0, 0, 255, 1)">var</span> readerStream = fs.createReadStream('input.txt'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 设置编码为 utf8。</span>
readerStream.setEncoding('UTF8'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 处理流事件 --> data, end, and error</span>
readerStream.on('data', <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(chunk) {
data </span>+=<span style="color: rgba(0, 0, 0, 1)"> chunk;
});
readerStream.on(</span>'end',<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(){
console.log(data);
});
readerStream.on(</span>'error', <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(err){
console.log(err.stack);
});
console.log(</span>"程序执行完毕");</pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p> </p>
<p>以上代码执行结果如下:</p>
<pre class="prettyprint prettyprinted"><span class="pun">程序执行完毕<span class="pln">
<span class="pun">mikey</span></span></span></pre>
<h2>写入流</h2>
<p>创建 main.js 文件, 代码如下:</p>
<div class="cnblogs_code"><img id="code_img_closed_4ccdd240-a9b7-484a-93f5-2c28a397be34" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_4ccdd240-a9b7-484a-93f5-2c28a397be34" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_4ccdd240-a9b7-484a-93f5-2c28a397be34" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> fs = require("fs"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> data = 'mikey'<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 创建一个可以写入的流,写入到文件 output.txt 中</span>
<span style="color: rgba(0, 0, 255, 1)">var</span> writerStream = fs.createWriteStream('output.txt'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 使用 utf8 编码写入数据</span>
writerStream.write(data,'UTF8'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 标记文件末尾</span>
<span style="color: rgba(0, 0, 0, 1)">writerStream.end();
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 处理流事件 --> data, end, and error</span>
writerStream.on('finish', <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">() {
console.log(</span>"写入完成。"<span style="color: rgba(0, 0, 0, 1)">);
});
writerStream.on(</span>'error', <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(err){
console.log(err.stack);
});
console.log(</span>"程序执行完毕");</pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p> </p>
<p>以上程序会将 data 变量的数据写入到 output.txt 文件中。代码执行结果如下:</p>
<div class="cnblogs_code">
<pre>$ node main.js </pre>
</div>
<pre class="prettyprint prettyprinted"><span class="pln"><span class="pun"><span class="pln"><span class="pun">程序执行完毕<span class="pln">
<span class="pun">写入完成。</span></span></span></span></span></span></pre>
<p>查看 output.txt 文件的内容:</p>
<div class="cnblogs_code">
<pre>$ cat output.txt </pre>
</div>
<pre class="prettyprint prettyprinted"><span class="pln"><span class="pun"><span class="pln"><span class="pun">菜鸟教程官网地址:<span class="pln">www<span class="pun">.<span class="pln">runoob<span class="pun">.<span class="pln">com</span></span></span></span></span></span></span></span></span></pre>
<h2>管道流</h2>
<p>管道提供了一个输出流到输入流的机制。通常我们用于从一个流中获取数据并将数据传递到另外一个流中。</p>
<p><img src="https://www.runoob.com/wp-content/uploads/2015/09/bVcla61" alt=""></p>
<p>如上面的图片所示,我们把文件比作装水的桶,而水就是文件里的内容,我们用一根管子(pipe)连接两个桶使得水从一个桶流入另一个桶,这样就慢慢的实现了大文件的复制过程。</p>
<p>以下实例我们通过读取一个文件内容并将内容写入到另外一个文件中。</p>
<p>设置 input.txt 文件内容如下:</p>
<pre class="prettyprint prettyprinted"><span class="pun"><span class="pln"><span class="pun"><span class="pln"><span class="pun"><span class="pln">mikey
<span class="pun">管道流操作实例</span></span></span></span></span></span></span></pre>
<p>创建 main.js 文件, 代码如下:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> fs = require("fs"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 创建一个可读流</span>
<span style="color: rgba(0, 0, 255, 1)">var</span> readerStream = fs.createReadStream('input.txt'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 创建一个可写流</span>
<span style="color: rgba(0, 0, 255, 1)">var</span> writerStream = fs.createWriteStream('output.txt'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 管道读写操作</span><span style="color: rgba(0, 128, 0, 1)">
//</span><span style="color: rgba(0, 128, 0, 1)"> 读取 input.txt 文件内容,并将内容写入到 output.txt 文件中</span>
<span style="color: rgba(0, 0, 0, 1)">readerStream.pipe(writerStream);
console.log(</span>"程序执行完毕");</pre>
</div>
<p> </p>
<p>代码执行结果如下:</p>
<div class="cnblogs_code">
<pre>$ node main.js </pre>
</div>
<pre class="prettyprint prettyprinted"><span class="pln"><span class="pun"><span class="pln"><span class="pun">程序执行完毕</span></span></span></span></pre>
<p>查看 output.txt 文件的内容:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">$ cat output.txt
mikey
管道流操作实例</span></pre>
</div>
<p> </p>
<h2>链式流</h2>
<p>链式是通过连接输出流到另外一个流并创建多个流操作链的机制。链式流一般用于管道操作。</p>
<p>接下来我们就是用管道和链式来压缩和解压文件。</p>
<p>创建 compress.js 文件, 代码如下:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> fs = require("fs"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> zlib = require('zlib'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 压缩 input.txt 文件为 input.txt.gz</span>
fs.createReadStream('input.txt'<span style="color: rgba(0, 0, 0, 1)">)
.pipe(zlib.createGzip())
.pipe(fs.createWriteStream(</span>'input.txt.gz'<span style="color: rgba(0, 0, 0, 1)">));
console.log(</span>"文件压缩完成。");</pre>
</div>
<p> </p>
<p>代码执行结果如下:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">$ node compress.js
文件压缩完成。</span></pre>
</div>
<p> </p>
<p>执行完以上操作后,我们可以看到当前目录下生成了 input.txt 的压缩文件 input.txt.gz。</p>
<p>接下来,让我们来解压该文件,创建 decompress.js 文件,代码如下:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> fs = require("fs"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> zlib = require('zlib'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 解压 input.txt.gz 文件为 input.txt</span>
fs.createReadStream('input.txt.gz'<span style="color: rgba(0, 0, 0, 1)">)
.pipe(zlib.createGunzip())
.pipe(fs.createWriteStream(</span>'input.txt'<span style="color: rgba(0, 0, 0, 1)">));
console.log(</span>"文件解压完成。");</pre>
</div>
<p> </p>
<p>代码执行结果如下:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">$ node decompress.js
文件解压完成。</span></pre>
</div>
<h1>Node.js模块系统</h1>
<p>为了让Node.js的文件可以相互调用,Node.js提供了一个简单的模块系统。</p>
<p>模块是Node.js 应用程序的基本组成部分,文件和模块是一一对应的。换言之,一个 Node.js 文件就是一个模块,这个文件可能是JavaScript 代码、JSON 或者编译过的C/C++ 扩展。</p>
<h2>创建模块</h2>
<p>在 Node.js 中,创建一个模块非常简单,如下我们创建一个 <strong>main.js</strong> 文件,代码如下:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> hello = require('./hello'<span style="color: rgba(0, 0, 0, 1)">);
hello.world();</span></pre>
</div>
<p> </p>
<p>以上实例中,代码 require('./hello') 引入了当前目录下的 hello.js 文件(./ 为当前目录,node.js 默认后缀为 js)。</p>
<p>Node.js 提供了 exports 和 require 两个对象,其中 exports 是模块公开的接口,require 用于从外部获取一个模块的接口,即所获取模块的 exports 对象。</p>
<p>接下来我们就来创建 hello.js 文件,代码如下:</p>
<div class="cnblogs_code">
<pre>exports.world = <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">() {
console.log(</span>'Hello World'<span style="color: rgba(0, 0, 0, 1)">);
}</span></pre>
</div>
<p> </p>
<p>在以上示例中,hello.js 通过 exports 对象把 world 作为模块的访问接口,在 main.js 中通过 require('./hello') 加载这个模块,然后就可以直接访 问 hello.js 中 exports 对象的成员函数了。</p>
<p>有时候我们只是想把一个对象封装到模块中,格式如下:</p>
<div class="cnblogs_code">
<pre>module.exports = <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">() {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> ...</span>
}</pre>
</div>
<p> </p>
<p>例如:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">hello.js </span>
<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> Hello() {
</span><span style="color: rgba(0, 0, 255, 1)">var</span><span style="color: rgba(0, 0, 0, 1)"> name;
</span><span style="color: rgba(0, 0, 255, 1)">this</span>.setName = <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(thyName) {
name </span>=<span style="color: rgba(0, 0, 0, 1)"> thyName;
};
</span><span style="color: rgba(0, 0, 255, 1)">this</span>.sayHello = <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">() {
console.log(</span>'Hello ' +<span style="color: rgba(0, 0, 0, 1)"> name);
};
};
module.exports </span>= Hello;</pre>
</div>
<p> </p>
<p>这样就可以直接获得这个对象了:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">main.js </span>
<span style="color: rgba(0, 0, 255, 1)">var</span> Hello = require('./hello'<span style="color: rgba(0, 0, 0, 1)">);
hello </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Hello();
hello.setName(</span>'BYVoid'<span style="color: rgba(0, 0, 0, 1)">);
hello.sayHello();</span></pre>
</div>
<p> </p>
<p>模块接口的唯一变化是使用 module.exports = Hello 代替了exports.world = function(){}。 在外部引用该模块时,其接口对象就是要输出的 Hello 对象本身,而不是原先的 exports。</p>
<h2>服务端的模块放在哪里</h2>
<p>也许你已经注意到,我们已经在代码中使用了模块了。像这样:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> http = require("http"<span style="color: rgba(0, 0, 0, 1)">);
...
http.createServer(...);</span></pre>
</div>
<p> </p>
<p>Node.js 中自带了一个叫做 <strong>http</strong> 的模块,我们在我们的代码中请求它并把返回值赋给一个本地变量。</p>
<p>这把我们的本地变量变成了一个拥有所有 http 模块所提供的公共方法的对象。</p>
<p>Node.js 的 require 方法中的文件查找策略如下:</p>
<p>由于 Node.js 中存在 4 类模块(原生模块和3种文件模块),尽管 require 方法极其简单,但是内部的加载却是十分复杂的,其加载优先级也各自不同。如下图所示:</p>
<p><img src="https://www.runoob.com/wp-content/uploads/2014/03/nodejs-require.jpg" alt=""></p>
<h3>从文件模块缓存中加载</h3>
<p>尽管原生模块与文件模块的优先级不同,但是都会优先从文件模块的缓存中加载已经存在的模块。</p>
<h3>从原生模块加载</h3>
<p>原生模块的优先级仅次于文件模块缓存的优先级。require 方法在解析文件名之后,优先检查模块是否在原生模块列表中。以http模块为例,尽管在目录下存在一个 http/http.js/http.node/http.json 文件,require("http") 都不会从这些文件中加载,而是从原生模块中加载。</p>
<p>原生模块也有一个缓存区,同样也是优先从缓存区加载。如果缓存区没有被加载过,则调用原生模块的加载方式进行加载和执行。</p>
<h3>从文件加载</h3>
<p>当文件模块缓存中不存在,而且不是原生模块的时候,Node.js 会解析 require 方法传入的参数,并从文件系统中加载实际的文件,加载过程中的包装和编译细节在前一节中已经介绍过,这里我们将详细描述查找文件模块的过程,其中,也有一些细节值得知晓。</p>
<p>require方法接受以下几种参数的传递:</p>
<ul>
<li>http、fs、path等,原生模块。</li>
<li>./mod或../mod,相对路径的文件模块。</li>
<li>/pathtomodule/mod,绝对路径的文件模块。</li>
<li>mod,非原生模块的文件模块。</li>
</ul>
<p>在路径 Y 下执行 require(X) 语句执行顺序:</p>
<div class="cnblogs_code"><img id="code_img_closed_f6ebc913-141d-4ff6-9fa5-1ad626789005" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_f6ebc913-141d-4ff6-9fa5-1ad626789005" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_f6ebc913-141d-4ff6-9fa5-1ad626789005" class="cnblogs_code_hide">
<pre>1<span style="color: rgba(0, 0, 0, 1)">. 如果 X 是内置模块
a. 返回内置模块
b. 停止执行
</span>2. 如果 X 以 '/'<span style="color: rgba(0, 0, 0, 1)"> 开头
a. 设置 Y 为文件根路径
</span>3. 如果 X 以 './' 或 '/' or '../'<span style="color: rgba(0, 0, 0, 1)"> 开头
a. LOAD_AS_FILE(Y </span>+<span style="color: rgba(0, 0, 0, 1)"> X)
b. LOAD_AS_DIRECTORY(Y </span>+<span style="color: rgba(0, 0, 0, 1)"> X)
</span>4<span style="color: rgba(0, 0, 0, 1)">. LOAD_NODE_MODULES(X, dirname(Y))
</span>5. 抛出异常 "not found"<span style="color: rgba(0, 0, 0, 1)">
LOAD_AS_FILE(X)
</span>1<span style="color: rgba(0, 0, 0, 1)">. 如果 X 是一个文件, 将 X 作为 JavaScript 文本载入并停止执行。
</span>2<span style="color: rgba(0, 0, 0, 1)">. 如果 X.js 是一个文件, 将 X.js 作为 JavaScript 文本载入并停止执行。
</span>3<span style="color: rgba(0, 0, 0, 1)">. 如果 X.json 是一个文件, 解析 X.json 为 JavaScript 对象并停止执行。
</span>4<span style="color: rgba(0, 0, 0, 1)">. 如果 X.node 是一个文件, 将 X.node 作为二进制插件载入并停止执行。
LOAD_INDEX(X)
</span>1. 如果 X/index.js 是一个文件,将 X/<span style="color: rgba(0, 0, 0, 1)">index.js 作为 JavaScript 文本载入并停止执行。
</span>2. 如果 X/index.json 是一个文件, 解析 X/<span style="color: rgba(0, 0, 0, 1)">index.json 为 JavaScript 对象并停止执行。
</span>3. 如果 X/index.node 是一个文件,将 X/<span style="color: rgba(0, 0, 0, 1)">index.node 作为二进制插件载入并停止执行。
LOAD_AS_DIRECTORY(X)
</span>1. 如果 X/package.json 是一个文件,
a. 解析 X/package.json, 并查找 "main" 字段。
b. let M = X +<span style="color: rgba(0, 0, 0, 1)"> (json main 字段)
c. LOAD_AS_FILE(M)
d. LOAD_INDEX(M)
</span>2<span style="color: rgba(0, 0, 0, 1)">. LOAD_INDEX(X)
LOAD_NODE_MODULES(X, START)
</span>1. let DIRS=<span style="color: rgba(0, 0, 0, 1)">NODE_MODULES_PATHS(START)
</span>2. <span style="color: rgba(0, 0, 255, 1)">for</span> each DIR <span style="color: rgba(0, 0, 255, 1)">in</span><span style="color: rgba(0, 0, 0, 1)"> DIRS:
a. LOAD_AS_FILE(DIR</span>/X)
b. LOAD_AS_DIRECTORY(DIR/X)
<span style="color: rgba(0, 0, 0, 1)">
NODE_MODULES_PATHS(START)
</span>1. let PARTS =<span style="color: rgba(0, 0, 0, 1)"> path split(START)
</span>2. let I = count of PARTS - 1
3. let DIRS =<span style="color: rgba(0, 0, 0, 1)"> []
</span>4. <span style="color: rgba(0, 0, 255, 1)">while</span> I >= 0<span style="color: rgba(0, 0, 0, 1)">,
a. </span><span style="color: rgba(0, 0, 255, 1)">if</span> PARTS = "node_modules"<span style="color: rgba(0, 0, 0, 1)"> CONTINUE
b. DIR </span>= path join(PARTS + "node_modules"<span style="color: rgba(0, 0, 0, 1)">)
c. DIRS </span>= DIRS +<span style="color: rgba(0, 0, 0, 1)"> DIR
d. let I </span>= I - 1
5. <span style="color: rgba(0, 0, 255, 1)">return</span> DIRS</pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p> </p>
<blockquote>
<p><strong>exports 和 module.exports 的使用</strong></p>
<p>如果要对外暴露属性或方法,就用 <strong>exports</strong> 就行,要暴露对象(类似class,包含了很多属性和方法),就用 <strong>module.exports</strong>。</p>
</blockquote>
<p> </p>
<h1>Node.js 函数</h1>
<p>在JavaScript中,一个函数可以作为另一个函数的参数。我们可以先定义一个函数,然后传递,也可以在传递参数的地方直接定义函数。</p>
<p>Node.js中函数的使用与Javascript类似,举例来说,你可以这样做:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> say(word) {
console.log(word);
}
</span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> execute(someFunction, value) {
someFunction(value);
}
execute(say, </span>"Hello");</pre>
</div>
<p> </p>
<p>以上代码中,我们把 say 函数作为execute函数的第一个变量进行了传递。这里传递的不是 say 的返回值,而是 say 本身!</p>
<p>这样一来, say 就变成了execute 中的本地变量 someFunction ,execute可以通过调用 someFunction() (带括号的形式)来使用 say 函数。</p>
<p>当然,因为 say 有一个变量, execute 在调用 someFunction 时可以传递这样一个变量。</p>
<h2>匿名函数</h2>
<p>我们可以把一个函数作为变量传递。但是我们不一定要绕这个"先定义,再传递"的圈子,我们可以直接在另一个函数的括号中定义和传递这个函数:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> execute(someFunction, value) {
someFunction(value);
}
execute(</span><span style="color: rgba(0, 0, 255, 1)">function</span>(word){ console.log(word) }, "Hello");</pre>
</div>
<p> </p>
<p>我们在 execute 接受第一个参数的地方直接定义了我们准备传递给 execute 的函数。</p>
<p>用这种方式,我们甚至不用给这个函数起名字,这也是为什么它被叫做匿名函数 。</p>
<h2>函数传递是如何让HTTP服务器工作的</h2>
<p>带着这些知识,我们再来看看我们简约而不简单的HTTP服务器:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> http = require("http"<span style="color: rgba(0, 0, 0, 1)">);
http.createServer(</span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(request, response) {
response.writeHead(</span>200, {"Content-Type": "text/plain"<span style="color: rgba(0, 0, 0, 1)">});
response.write(</span>"Hello World"<span style="color: rgba(0, 0, 0, 1)">);
response.end();
}).listen(</span>8888);</pre>
</div>
<p> </p>
<p>现在它看上去应该清晰了很多:我们向 createServer 函数传递了一个匿名函数。</p>
<p>用这样的代码也可以达到同样的目的:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> http = require("http"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> onRequest(request, response) {
response.writeHead(</span>200, {"Content-Type": "text/plain"<span style="color: rgba(0, 0, 0, 1)">});
response.write(</span>"Hello World"<span style="color: rgba(0, 0, 0, 1)">);
response.end();
}
http.createServer(onRequest).listen(</span>8888);</pre>
</div>
<h1>Node.js 路由</h1>
<p>我们要为路由提供请求的 URL 和其他需要的 GET 及 POST 参数,随后路由需要根据这些数据来执行相应的代码。</p>
<p>因此,我们需要查看 HTTP 请求,从中提取出请求的 URL 以及 GET/POST 参数。这一功能应当属于路由还是服务器(甚至作为一个模块自身的功能)确实值得探讨,但这里暂定其为我们的HTTP服务器的功能。</p>
<p>我们需要的所有数据都会包含在 request 对象中,该对象作为 onRequest() 回调函数的第一个参数传递。但是为了解析这些数据,我们需要额外的 Node.JS 模块,它们分别是 url 和 querystring 模块。</p>
<div class="cnblogs_code"><img id="code_img_closed_b4a22c9e-5a34-481f-ad5e-e833689b1949" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_b4a22c9e-5a34-481f-ad5e-e833689b1949" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_b4a22c9e-5a34-481f-ad5e-e833689b1949" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 0, 1)"> url.parse(string).query
</span>|<span style="color: rgba(0, 0, 0, 1)">
url.parse(string).pathname </span>|
| |
| |
------ -------------------<span style="color: rgba(0, 0, 0, 1)">
http:</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">localhost:8888/start?foo=bar&hello=world</span>
--- -----
| |
| |<span style="color: rgba(0, 0, 0, 1)">
querystring.parse(queryString)[</span>"foo"] |
|<span style="color: rgba(0, 0, 0, 1)">
querystring.parse(queryString)[</span>"hello"]</pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p> </p>
<p>当然我们也可以用 querystring 模块来解析 POST 请求体中的参数,稍后会有演示。</p>
<p>现在我们来给 onRequest() 函数加上一些逻辑,用来找出浏览器请求的 URL 路径:</p>
<div class="example">
<h2 class="example">server.js 文件代码:</h2>
<div class="example_code">
<div class="hl-main">
<div class="cnblogs_code"><img id="code_img_closed_5d04aa19-4b9d-40dd-9b05-0ffecc3ea757" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_5d04aa19-4b9d-40dd-9b05-0ffecc3ea757" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_5d04aa19-4b9d-40dd-9b05-0ffecc3ea757" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> http = require('http'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> url = require('url'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> start(router) {
</span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> onRequest(request, response) {
</span><span style="color: rgba(0, 0, 255, 1)">var</span> pathname =<span style="color: rgba(0, 0, 0, 1)"> url.parse(request.url).pathname;
console.log(</span>'请求路径:'+<span style="color: rgba(0, 0, 0, 1)">pathname);
router(pathname);
response.writeHead(</span>200, {"Content-Type":"text/plain"<span style="color: rgba(0, 0, 0, 1)">});
response.write(</span>"hello world"<span style="color: rgba(0, 0, 0, 1)">);
response.end();
}
http.createServer(onRequest).listen(</span>8888<span style="color: rgba(0, 0, 0, 1)">);
console.log(</span>'服务已经启动'<span style="color: rgba(0, 0, 0, 1)">);
}
exports.start </span>= start;</pre>
</div>
<span class="cnblogs_code_collapse">Server.js</span></div>
<p> </p>
</div>
</div>
</div>
<p>好了,我们的应用现在可以通过请求的 URL 路径来区别不同请求了--这使我们得以使用路由(还未完成)来将请求以 URL 路径为基准映射到处理程序上。</p>
<p>在我们所要构建的应用中,这意味着来自 /start 和 /upload 的请求可以使用不同的代码来处理。稍后我们将看到这些内容是如何整合到一起的。</p>
<p>现在我们可以来编写路由了,建立一个名为 <strong>router.js</strong> 的文件,添加以下内容:</p>
<div class="example">
<h2 class="example">router.js 文件代码:</h2>
<div class="example_code">
<div class="hl-main">
<div class="cnblogs_code"><img id="code_img_closed_ab069940-0db3-4397-8852-62e501933314" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_ab069940-0db3-4397-8852-62e501933314" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_ab069940-0db3-4397-8852-62e501933314" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> router(pathname) {
console.log(</span>"about to route a request for " +<span style="color: rgba(0, 0, 0, 1)"> pathname);
}
exports.router </span>= router;</pre>
</div>
<span class="cnblogs_code_collapse">Router.js</span></div>
<p> </p>
</div>
</div>
</div>
<p>如你所见,这段代码什么也没干,不过对于现在来说这是应该的。在添加更多的逻辑以前,我们先来看看如何把路由和服务器整合起来。</p>
<p>我们的服务器应当知道路由的存在并加以有效利用。我们当然可以通过硬编码的方式将这一依赖项绑定到服务器上,但是其它语言的编程经验告诉我们这会是一件非常痛苦的事,因此我们将使用依赖注入的方式较松散地添加路由模块。</p>
<p>首先,我们来扩展一下服务器的 start() 函数,以便将路由函数作为参数传递过去,<strong>server.js</strong> 文件代码如下</p>
<div class="example">
<h2 class="example">server.js 文件代码:</h2>
<div class="example_code">
<div class="hl-main">
<div class="cnblogs_code"><img id="code_img_closed_7bee721e-435d-4dd8-b617-58a7b901e885" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_7bee721e-435d-4dd8-b617-58a7b901e885" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_7bee721e-435d-4dd8-b617-58a7b901e885" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> http = require('http'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> url = require('url'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> start(router) {
</span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> onRequest(request, response) {
</span><span style="color: rgba(0, 0, 255, 1)">var</span> pathname =<span style="color: rgba(0, 0, 0, 1)"> url.parse(request.url).pathname;
console.log(</span>'请求路径:'+<span style="color: rgba(0, 0, 0, 1)">pathname);
router(pathname);
response.writeHead(</span>200, {"Content-Type":"text/plain"<span style="color: rgba(0, 0, 0, 1)">});
response.write(</span>"hello world"<span style="color: rgba(0, 0, 0, 1)">);
response.end();
}
http.createServer(onRequest).listen(</span>8888<span style="color: rgba(0, 0, 0, 1)">);
console.log(</span>'服务已经启动'<span style="color: rgba(0, 0, 0, 1)">);
}
exports.start </span>= start;</pre>
</div>
<span class="cnblogs_code_collapse">Server.js</span></div>
<p> </p>
</div>
</div>
</div>
<p>同时,我们会相应扩展 index.js,使得路由函数可以被注入到服务器中:</p>
<div class="example">
<h2 class="example">index.js 文件代码:</h2>
<div class="example_code">
<div class="hl-main">
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> server = require('./Server'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> router = require('./router'<span style="color: rgba(0, 0, 0, 1)">);
server.start(router.router);</span></pre>
</div>
<p> </p>
</div>
</div>
</div>
<p>在这里,我们传递的函数依旧什么也没做。</p>
<p>如果现在启动应用(node index.js,始终记得这个命令行),随后请求一个URL,你将会看到应用输出相应的信息,这表明我们的HTTP服务器已经在使用路由模块了,并会将请求的路径传递给路由:</p>
<p><img src="https://img2018.cnblogs.com/blog/1399348/201910/1399348-20191004161859036-877448476.png" alt=""></p>
<p>以上输出已经去掉了比较烦人的 /favicon.ico 请求相关的部分。</p>
<p>浏览器访问 <strong>http://127.0.0.1:8888/</strong>,输出结果如下:</p>
<p><img src="https://img2018.cnblogs.com/blog/1399348/201910/1399348-20191004161914870-1938320171.png" alt="" width="886" height="177"></p>
<h1>Node.js 全局对象</h1>
<p>JavaScript 中有一个特殊的对象,称为全局对象(Global Object),它及其所有属性都可以在程序的任何地方访问,即全局变量。</p>
<p>在浏览器 JavaScript 中,通常 window 是全局对象, 而 Node.js 中的全局对象是 global,所有全局变量(除了 global 本身以外)都是 global 对象的属性。</p>
<p>在 Node.js 我们可以直接访问到 global 的属性,而不需要在应用中包含它。</p>
<h2>全局对象与全局变量</h2>
<p>global 最根本的作用是作为全局变量的宿主。按照 ECMAScript 的定义,满足以下条 件的变量是全局变量:</p>
<ul>
<li>在最外层定义的变量;</li>
<li>全局对象的属性;</li>
<li>隐式定义的变量(未定义直接赋值的变量)。</li>
</ul>
<p>当你定义一个全局变量时,这个变量同时也会成为全局对象的属性,反之亦然。需要注 意的是,在 Node.js 中你不可能在最外层定义变量,因为所有用户代码都是属于当前模块的, 而模块本身不是最外层上下文。</p>
<p><strong>注意:</strong> 最好不要使用 var 定义变量以避免引入全局变量,因为全局变量会污染命名空间,提高代码的耦合风险。</p>
<h2>__filename</h2>
<p><strong>__filename</strong> 表示当前正在执行的脚本的文件名。它将输出文件所在位置的绝对路径,且和命令行参数所指定的文件名不一定相同。 如果在模块中,返回的值是模块文件的路径。</p>
<h3>实例</h3>
<p>创建文件 main.js ,代码如下所示:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 输出全局变量 __filename 的值</span>
console.log( __filename );</pre>
</div>
<p> </p>
<p>执行 main.js 文件,代码如下所示:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">$ node main.js
</span>/web/com/runoob/nodejs/main.js</pre>
</div>
<p> </p>
<h2>__dirname</h2>
<p><strong>__dirname</strong> 表示当前执行脚本所在的目录。</p>
<h3>实例</h3>
<p>创建文件 main.js ,代码如下所示:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 输出全局变量 __dirname 的值</span>
console.log( __dirname );</pre>
</div>
<p> </p>
<p>执行 main.js 文件,代码如下所示:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">$ node main.js
</span>/web/com/runoob/nodejs</pre>
</div>
<p> </p>
<h2>setTimeout(cb, ms)</h2>
<p><strong>setTimeout(cb, ms)</strong> 全局函数在指定的毫秒(ms)数后执行指定函数(cb)。:setTimeout() 只执行一次指定函数。</p>
<p>返回一个代表定时器的句柄值。</p>
<h3>实例</h3>
<p>创建文件 main.js ,代码如下所示:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> printHello(){
console.log( </span>"Hello, World!"<span style="color: rgba(0, 0, 0, 1)">);
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 两秒后执行以上函数</span>
setTimeout(printHello, 2000);</pre>
</div>
<p> </p>
<p>执行 main.js 文件,代码如下所示:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">$ node main.js
Hello, World</span>!</pre>
</div>
<p> </p>
<h2>clearTimeout(t)</h2>
<p><strong>clearTimeout( t )</strong> 全局函数用于停止一个之前通过 setTimeout() 创建的定时器。 参数 <strong>t</strong> 是通过 setTimeout() 函数创建的定时器。</p>
<h3>实例</h3>
<p>创建文件 main.js ,代码如下所示:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> printHello(){
console.log( </span>"Hello, World!"<span style="color: rgba(0, 0, 0, 1)">);
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 两秒后执行以上函数</span>
<span style="color: rgba(0, 0, 255, 1)">var</span> t = setTimeout(printHello, 2000<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 清除定时器</span>
clearTimeout(t);</pre>
</div>
<p> </p>
<p>执行 main.js 文件,代码如下所示:</p>
<div class="cnblogs_code">
<pre>$ node main.js</pre>
</div>
<p> </p>
<h2>setInterval(cb, ms)</h2>
<p><strong>setInterval(cb, ms)</strong> 全局函数在指定的毫秒(ms)数后执行指定函数(cb)。</p>
<p>返回一个代表定时器的句柄值。可以使用 <strong>clearInterval(t)</strong> 函数来清除定时器。</p>
<p>setInterval() 方法会不停地调用函数,直到 clearInterval() 被调用或窗口被关闭。</p>
<h3>实例</h3>
<p>创建文件 main.js ,代码如下所示:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> printHello(){
console.log( </span>"Hello, World!"<span style="color: rgba(0, 0, 0, 1)">);
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 两秒后执行以上函数</span>
setInterval(printHello, 2000);</pre>
</div>
<p> </p>
<p>执行 main.js 文件,代码如下所示:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">$ node main.js
Hello, World</span>! Hello, World! Hello, World! Hello, World! Hello, World! ……</pre>
</div>
<p> </p>
<p>以上程序每隔两秒就会输出一次"Hello, World!",且会永久执行下去,直到你按下 <strong>ctrl + c</strong> 按钮。</p>
<h2>console</h2>
<p>console 用于提供控制台标准输出,它是由 Internet Explorer 的 JScript 引擎提供的调试工具,后来逐渐成为浏览器的实施标准。</p>
<p>Node.js 沿用了这个标准,提供与习惯行为一致的 console 对象,用于向标准输出流(stdout)或标准错误流(stderr)输出字符。</p>
<h3>console 方法</h3>
<p>以下为 console 对象的方法:</p>
<table class="reference">
<tbody>
<tr><th>序号</th><th>方法 & 描述</th></tr>
<tr>
<td>1</td>
<td><strong>console.log([, ...])</strong><br>向标准输出流打印字符并以换行符结束。该方法接收若干 个参数,如果只有一个参数,则输出这个参数的字符串形式。如果有多个参数,则 以类似于C 语言 printf() 命令的格式输出。</td>
</tr>
<tr>
<td>2</td>
<td><strong>console.info([, ...])</strong><br>该命令的作用是返回信息性消息,这个命令与console.log差别并不大,除了在chrome中只会输出文字外,其余的会显示一个蓝色的惊叹号。</td>
</tr>
<tr>
<td>3</td>
<td><strong>console.error([, ...])</strong><br>输出错误消息的。控制台在出现错误时会显示是红色的叉子。</td>
</tr>
<tr>
<td>4</td>
<td><strong>console.warn([, ...])</strong><br>输出警告消息。控制台出现有黄色的惊叹号。</td>
</tr>
<tr>
<td>5</td>
<td><strong>console.dir(obj[, options])</strong><br>用来对一个对象进行检查(inspect),并以易于阅读和打印的格式显示。</td>
</tr>
<tr>
<td>6</td>
<td><strong>console.time(label)</strong><br>输出时间,表示计时开始。</td>
</tr>
<tr>
<td>7</td>
<td><strong>console.timeEnd(label)</strong><br>结束时间,表示计时结束。</td>
</tr>
<tr>
<td>8</td>
<td><strong>console.trace(message[, ...])</strong><br>当前执行的代码在堆栈中的调用路径,这个测试函数运行很有帮助,只要给想测试的函数里面加入 console.trace 就行了。</td>
</tr>
<tr>
<td>9</td>
<td><strong>console.assert(value[, message][, ...])</strong><br>用于判断某个表达式或变量是否为真,接收两个参数,第一个参数是表达式,第二个参数是字符串。只有当第一个参数为false,才会输出第二个参数,否则不会有任何结果。</td>
</tr>
</tbody>
</table>
<p>
console.log():向标准输出流打印字符并以换行符结束。</p>
<p> </p>
<p>console.log 接收若干 个参数,如果只有一个参数,则输出这个参数的字符串形式。如果有多个参数,则 以类似于C 语言 printf() 命令的格式输出。</p>
<p>第一个参数是一个字符串,如果没有 参数,只打印一个换行。</p>
<div class="cnblogs_code">
<pre>console.log('Hello world'<span style="color: rgba(0, 0, 0, 1)">);
console.log(</span>'byvoid%diovyb'<span style="color: rgba(0, 0, 0, 1)">);
console.log(</span>'byvoid%diovyb', 1991);</pre>
</div>
<p> </p>
<p>运行结果为:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">Hello world
byvoid</span>%<span style="color: rgba(0, 0, 0, 1)">diovyb
byvoid1991iovyb </span></pre>
</div>
<p> </p>
<ul>
<li>console.error():与console.log() 用法相同,只是向标准错误流输出。</li>
<li>console.trace():向标准错误流输出当前的调用栈。</li>
</ul>
<pre class="prettyprint prettyprinted"><span class="pln">console<span class="pun">.<span class="pln">trace<span class="pun">();</span></span></span></span></pre>
<p>运行结果为:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">Trace:
at Object.</span><anonymous> (/home/byvoid/consoletrace.js:1:71)
at Module._compile (module.js:441:26<span style="color: rgba(0, 0, 0, 1)">)
at Object..js (module.js:</span>459:10<span style="color: rgba(0, 0, 0, 1)">)
at Module.load (module.js:</span>348:31<span style="color: rgba(0, 0, 0, 1)">)
at Function._load (module.js:</span>308:12<span style="color: rgba(0, 0, 0, 1)">)
at Array.</span>0 (module.js:479:10<span style="color: rgba(0, 0, 0, 1)">)
at EventEmitter._tickCallback (node.js:</span>192:40)</pre>
</div>
<p> </p>
<h3>实例</h3>
<p>创建文件 main.js ,代码如下所示:</p>
<div class="cnblogs_code">
<pre>console.info("程序开始执行:"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> counter = 10<span style="color: rgba(0, 0, 0, 1)">;
console.log(</span>"计数: %d"<span style="color: rgba(0, 0, 0, 1)">, counter);
console.time(</span>"获取数据"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 0, 1)">//
//</span><span style="color: rgba(0, 128, 0, 1)"> 执行一些代码</span><span style="color: rgba(0, 128, 0, 1)">
//</span>
console.timeEnd('获取数据'<span style="color: rgba(0, 0, 0, 1)">);
console.info(</span>"程序执行完毕。")</pre>
</div>
<p> </p>
<p>执行 main.js 文件,代码如下所示:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">$ node main.js
程序开始执行:
计数: </span>10<span style="color: rgba(0, 0, 0, 1)">
获取数据: 0ms
程序执行完毕</span></pre>
</div>
<p> </p>
<h2>process</h2>
<p>process 是一个全局变量,即 global 对象的属性。</p>
<p>它用于描述当前Node.js 进程状态的对象,提供了一个与操作系统的简单接口。通常在你写本地命令行程序的时候,少不了要 和它打交道。下面将会介绍 process 对象的一些最常用的成员方法。</p>
<table class="reference">
<tbody>
<tr><th>序号</th><th>事件 & 描述</th></tr>
<tr>
<td>1</td>
<td><strong>exit</strong><br>当进程准备退出时触发。</td>
</tr>
<tr>
<td>2</td>
<td><strong>beforeExit</strong><br>当 node 清空事件循环,并且没有其他安排时触发这个事件。通常来说,当没有进程安排时 node 退出,但是 'beforeExit' 的监听器可以异步调用,这样 node 就会继续执行。</td>
</tr>
<tr>
<td>3</td>
<td><strong>uncaughtException</strong><br>当一个异常冒泡回到事件循环,触发这个事件。如果给异常添加了监视器,默认的操作(打印堆栈跟踪信息并退出)就不会发生。</td>
</tr>
<tr>
<td>4</td>
<td><strong>Signal 事件</strong><br>当进程接收到信号时就触发。信号列表详见标准的 POSIX 信号名,如 SIGINT、SIGUSR1 等。</td>
</tr>
</tbody>
</table>
<h3>实例</h3>
<p>创建文件 main.js ,代码如下所示:</p>
<div class="cnblogs_code">
<pre>process.on('exit', <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(code) {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 以下代码永远不会执行</span>
setTimeout(<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">() {
console.log(</span>"该代码不会执行"<span style="color: rgba(0, 0, 0, 1)">);
}, </span>0<span style="color: rgba(0, 0, 0, 1)">);
console.log(</span>'退出码为:'<span style="color: rgba(0, 0, 0, 1)">, code);
});
console.log(</span>"程序执行结束");</pre>
</div>
<p> </p>
<p>执行 main.js 文件,代码如下所示:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">$ node main.js
程序执行结束
退出码为: </span>0</pre>
</div>
<p> </p>
<h3>退出状态码</h3>
<p>退出状态码如下所示:</p>
<table class="reference">
<tbody>
<tr><th>状态码</th><th>名称 & 描述</th></tr>
<tr>
<td>1</td>
<td><strong>Uncaught Fatal Exception</strong><br>有未捕获异常,并且没有被域或 uncaughtException 处理函数处理。</td>
</tr>
<tr>
<td>2</td>
<td><strong>Unused</strong><br>保留</td>
</tr>
<tr>
<td>3</td>
<td><strong>Internal JavaScript Parse Error</strong><br>JavaScript的源码启动 Node 进程时引起解析错误。非常罕见,仅会在开发 Node 时才会有。</td>
</tr>
<tr>
<td>4</td>
<td><strong>Internal JavaScript Evaluation Failure</strong><br>JavaScript 的源码启动 Node 进程,评估时返回函数失败。非常罕见,仅会在开发 Node 时才会有。</td>
</tr>
<tr>
<td>5</td>
<td><strong>Fatal Error</strong><br>V8 里致命的不可恢复的错误。通常会打印到 stderr ,内容为: FATAL ERROR</td>
</tr>
<tr>
<td>6</td>
<td><strong>Non-function Internal Exception Handler</strong><br>未捕获异常,内部异常处理函数不知为何设置为on-function,并且不能被调用。</td>
</tr>
<tr>
<td>7</td>
<td><strong>Internal Exception Handler Run-Time Failure</strong><br>未捕获的异常, 并且异常处理函数处理时自己抛出了异常。例如,如果 process.on('uncaughtException') 或 domain.on('error') 抛出了异常。</td>
</tr>
<tr>
<td>8</td>
<td><strong>Unused</strong><br>保留</td>
</tr>
<tr>
<td>9</td>
<td><strong>Invalid Argument</strong><br>可能是给了未知的参数,或者给的参数没有值。</td>
</tr>
<tr>
<td>10</td>
<td><strong>Internal JavaScript Run-Time Failure</strong><br>JavaScript的源码启动 Node 进程时抛出错误,非常罕见,仅会在开发 Node 时才会有。</td>
</tr>
<tr>
<td>12</td>
<td><strong>Invalid Debug Argument</strong><br>设置了参数--debug 和/或 --debug-brk,但是选择了错误端口。</td>
</tr>
<tr>
<td>128</td>
<td><strong>Signal Exits</strong><br>如果 Node 接收到致命信号,比如SIGKILL 或 SIGHUP,那么退出代码就是128 加信号代码。这是标准的 Unix 做法,退出信号代码放在高位。</td>
</tr>
</tbody>
</table>
<h3>Process 属性</h3>
<p>Process 提供了很多有用的属性,便于我们更好的控制系统的交互:</p>
<table class="reference">
<tbody>
<tr><th>序号.</th><th>属性 & 描述</th></tr>
<tr>
<td>1</td>
<td><strong>stdout</strong><br>标准输出流。</td>
</tr>
<tr>
<td>2</td>
<td><strong>stderr</strong><br>标准错误流。</td>
</tr>
<tr>
<td>3</td>
<td><strong>stdin</strong><br>标准输入流。</td>
</tr>
<tr>
<td>4</td>
<td><strong>argv</strong><br>argv 属性返回一个数组,由命令行执行脚本时的各个参数组成。它的第一个成员总是node,第二个成员是脚本文件名,其余成员是脚本文件的参数。</td>
</tr>
<tr>
<td>5</td>
<td><strong>execPath</strong><br>返回执行当前脚本的 Node 二进制文件的绝对路径。</td>
</tr>
<tr>
<td>6</td>
<td><strong>execArgv</strong><br>返回一个数组,成员是命令行下执行脚本时,在Node可执行文件与脚本文件之间的命令行参数。</td>
</tr>
<tr>
<td>7</td>
<td><strong>env</strong><br>返回一个对象,成员为当前 shell 的环境变量</td>
</tr>
<tr>
<td>8</td>
<td><strong>exitCode</strong><br>进程退出时的代码,如果进程优通过 process.exit() 退出,不需要指定退出码。</td>
</tr>
<tr>
<td>9</td>
<td><strong>version</strong><br>Node 的版本,比如v0.10.18。</td>
</tr>
<tr>
<td>10</td>
<td><strong>versions</strong><br>一个属性,包含了 node 的版本和依赖.</td>
</tr>
<tr>
<td>11</td>
<td><strong>config</strong><br>一个包含用来编译当前 node 执行文件的 javascript 配置选项的对象。它与运行 ./configure 脚本生成的 "config.gypi" 文件相同。</td>
</tr>
<tr>
<td>12</td>
<td><strong>pid</strong><br>当前进程的进程号。</td>
</tr>
<tr>
<td>13</td>
<td><strong>title</strong><br>进程名,默认值为"node",可以自定义该值。</td>
</tr>
<tr>
<td>14</td>
<td><strong>arch</strong><br>当前 CPU 的架构:'arm'、'ia32' 或者 'x64'。</td>
</tr>
<tr>
<td>15</td>
<td><strong>platform</strong><br>运行程序所在的平台系统 'darwin', 'freebsd', 'linux', 'sunos' 或 'win32'</td>
</tr>
<tr>
<td>16</td>
<td><strong>mainModule</strong><br>require.main 的备选方法。不同点,如果主模块在运行时改变,require.main可能会继续返回老的模块。可以认为,这两者引用了同一个模块。</td>
</tr>
</tbody>
</table>
<h3>实例</h3>
<p>创建文件 main.js ,代码如下所示:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 输出到终端</span>
process.stdout.write("Hello World!" + "\n"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 通过参数读取</span>
process.argv.forEach(<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(val, index, array) {
console.log(index </span>+ ': ' +<span style="color: rgba(0, 0, 0, 1)"> val);
});
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 获取执行路径</span>
<span style="color: rgba(0, 0, 0, 1)">console.log(process.execPath);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 平台信息</span>
console.log(process.platform);</pre>
</div>
<p> </p>
<p>执行 main.js 文件,结果如下所示:</p>
<div class="cnblogs_code">
<pre>Hello World!
0<span style="color: rgba(0, 0, 0, 1)">: node
</span>1: /web/www/node/<span style="color: rgba(0, 0, 0, 1)">main.js
</span>/usr/local/node/0.10.36/bin/<span style="color: rgba(0, 0, 0, 1)">node
darwin</span></pre>
</div>
<h3>方法参考手册</h3>
<p>Process 提供了很多有用的方法,便于我们更好的控制系统的交互:</p>
<table class="reference">
<tbody>
<tr><th>序号</th><th>方法 & 描述</th></tr>
<tr>
<td>1</td>
<td><strong>abort()</strong><br>这将导致 node 触发 abort 事件。会让 node 退出并生成一个核心文件。</td>
</tr>
<tr>
<td>2</td>
<td><strong>chdir(directory)</strong><br>改变当前工作进程的目录,如果操作失败抛出异常。</td>
</tr>
<tr>
<td>3</td>
<td><strong>cwd()</strong><br>返回当前进程的工作目录</td>
</tr>
<tr>
<td>4</td>
<td><strong>exit()</strong><br>使用指定的 code 结束进程。如果忽略,将会使用 code 0。</td>
</tr>
<tr>
<td>5</td>
<td><strong>getgid()</strong><br>获取进程的群组标识(参见 getgid(2))。获取到得时群组的数字 id,而不是名字。<br>注意:这个函数仅在 POSIX 平台上可用(例如,非Windows 和 Android)。</td>
</tr>
<tr>
<td>6</td>
<td><strong>setgid(id)</strong><br>设置进程的群组标识(参见 setgid(2))。可以接收数字 ID 或者群组名。如果指定了群组名,会阻塞等待解析为数字 ID 。<br>注意:这个函数仅在 POSIX 平台上可用(例如,非Windows 和 Android)。</td>
</tr>
<tr>
<td>7</td>
<td><strong>getuid()</strong><br>获取进程的用户标识(参见 getuid(2))。这是数字的用户 id,不是用户名。<br>注意:这个函数仅在 POSIX 平台上可用(例如,非Windows 和 Android)。</td>
</tr>
<tr>
<td>8</td>
<td><strong>setuid(id)</strong><br>设置进程的用户标识(参见setuid(2))。接收数字 ID或字符串名字。果指定了群组名,会阻塞等待解析为数字 ID 。<br>注意:这个函数仅在 POSIX 平台上可用(例如,非Windows 和 Android)。</td>
</tr>
<tr>
<td>9</td>
<td><strong>getgroups()</strong><br>返回进程的群组 iD 数组。POSIX 系统没有保证一定有,但是 node.js 保证有。<br>注意:这个函数仅在 POSIX 平台上可用(例如,非Windows 和 Android)。</td>
</tr>
<tr>
<td>10</td>
<td><strong>setgroups(groups)</strong><br>设置进程的群组 ID。这是授权操作,所以你需要有 root 权限,或者有 CAP_SETGID 能力。<br>注意:这个函数仅在 POSIX 平台上可用(例如,非Windows 和 Android)。</td>
</tr>
<tr>
<td>11</td>
<td><strong>initgroups(user, extra_group)</strong><br>读取 /etc/group ,并初始化群组访问列表,使用成员所在的所有群组。这是授权操作,所以你需要有 root 权限,或者有 CAP_SETGID 能力。<br>注意:这个函数仅在 POSIX 平台上可用(例如,非Windows 和 Android)。</td>
</tr>
<tr>
<td>12</td>
<td><strong>kill(pid[, signal])</strong><br>发送信号给进程. pid 是进程id,并且 signal 是发送的信号的字符串描述。信号名是字符串,比如 'SIGINT' 或 'SIGHUP'。如果忽略,信号会是 'SIGTERM'。</td>
</tr>
<tr>
<td>13</td>
<td><strong>memoryUsage()</strong><br>返回一个对象,描述了 Node 进程所用的内存状况,单位为字节。</td>
</tr>
<tr>
<td>14</td>
<td><strong>nextTick(callback)</strong><br>一旦当前事件循环结束,调用回调函数。</td>
</tr>
<tr>
<td>15</td>
<td><strong>umask()</strong><br>设置或读取进程文件的掩码。子进程从父进程继承掩码。如果mask 参数有效,返回旧的掩码。否则,返回当前掩码。</td>
</tr>
<tr>
<td>16</td>
<td><strong>uptime()</strong><br>返回 Node 已经运行的秒数。</td>
</tr>
<tr>
<td>17</td>
<td><strong>hrtime()</strong><br>返回当前进程的高分辨时间,形式为 数组。它是相对于过去的任意事件。该值与日期无关,因此不受时钟漂移的影响。主要用途是可以通过精确的时间间隔,来衡量程序的性能。<br>你可以将之前的结果传递给当前的 process.hrtime() ,会返回两者间的时间差,用来基准和测量时间间隔。</td>
</tr>
</tbody>
</table>
<h3>实例</h3>
<p>创建文件 main.js ,代码如下所示:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 输出当前目录</span>
console.log('当前目录: ' +<span style="color: rgba(0, 0, 0, 1)"> process.cwd());
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 输出当前版本</span>
console.log('当前版本: ' +<span style="color: rgba(0, 0, 0, 1)"> process.version);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 输出内存使用情况</span>
console.log(process.memoryUsage());</pre>
</div>
<p> </p>
<p>执行 main.js 文件,代码如下所示:</p>
<div class="cnblogs_code">
<pre>当前目录: /web/com/runoob/<span style="color: rgba(0, 0, 0, 1)">nodejs
当前版本: v0.</span>10.36<span style="color: rgba(0, 0, 0, 1)">
{ rss: </span>12541952, heapTotal: 4083456, heapUsed: 2157056 }</pre>
</div>
<h1>Node.js 常用工具</h1>
<p>util 是一个Node.js 核心模块,提供常用函数的集合,用于弥补核心JavaScript 的功能 过于精简的不足。</p>
<h2>util.inherits</h2>
<p><span class="marked">util.inherits(constructor, superConstructor) 是一个实现对象间原型继承的函数。</span></p>
<p>JavaScript 的面向对象特性是基于原型的,与常见的基于类的不同。JavaScript 没有提供对象继承的语言级别特性,而是通过原型复制来实现的。</p>
<p>在这里我们只介绍 util.inherits 的用法,示例如下:</p>
<div class="cnblogs_code"><img id="code_img_closed_cf00c473-6146-44f8-b40e-5aa0944e678d" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_cf00c473-6146-44f8-b40e-5aa0944e678d" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_cf00c473-6146-44f8-b40e-5aa0944e678d" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> util = require('util'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> Base() {
</span><span style="color: rgba(0, 0, 255, 1)">this</span>.name = 'base'<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">this</span>.base = 1991<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">this</span>.sayHello = <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">() {
console.log(</span>'Hello ' + <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.name);
};
}
Base.prototype.showName </span>= <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">() {
console.log(</span><span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.name);
};
</span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> Sub() {
</span><span style="color: rgba(0, 0, 255, 1)">this</span>.name = 'sub'<span style="color: rgba(0, 0, 0, 1)">;
}
util.inherits(Sub, Base);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> objBase = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Base();
objBase.showName();
objBase.sayHello();
console.log(objBase);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> objSub = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Sub();
objSub.showName();
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">objSub.sayHello(); </span>
console.log(objSub);</pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p> </p>
<p>我们定义了一个基础对象 Base 和一个继承自 Base 的 Sub,Base 有三个在构造函数内定义的属性和一个原型中定义的函数,通过util.inherits 实现继承。运行结果如下:</p>
<div class="cnblogs_code"><img id="code_img_closed_0ab60eab-ae42-4270-b65f-f6124c83d44f" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_0ab60eab-ae42-4270-b65f-f6124c83d44f" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_0ab60eab-ae42-4270-b65f-f6124c83d44f" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 0, 1)">base
Hello base
{ name: </span>'base', base: 1991<span style="color: rgba(0, 0, 0, 1)">, sayHello: }
sub
{ name: </span>'sub' }</pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p> </p>
<p><strong>注意:</strong>Sub 仅仅继承了Base 在原型中定义的函数,而构造函数内部创造的 base 属 性和 sayHello 函数都没有被 Sub 继承。</p>
<p>同时,在原型中定义的属性不会被 console.log 作 为对象的属性输出。如果我们去掉 objSub.sayHello(); 这行的注释,将会看到:</p>
<div class="cnblogs_code"><img id="code_img_closed_101add84-4b21-4fdc-b2e8-51074893147d" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_101add84-4b21-4fdc-b2e8-51074893147d" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_101add84-4b21-4fdc-b2e8-51074893147d" class="cnblogs_code_hide">
<pre>node.js:201
<span style="color: rgba(0, 0, 255, 1)">throw</span> e; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> process.nextTick error, or 'error' event on first tick </span>
^<span style="color: rgba(0, 0, 0, 1)">
TypeError: Object #</span>&lt;Sub&gt; has no method 'sayHello'<span style="color: rgba(0, 0, 0, 1)">
at Object.</span>&lt;anonymous&gt; (/home/byvoid/utilinherits.js:29:8)
at Module._compile (module.js:441:26<span style="color: rgba(0, 0, 0, 1)">)
at Object..js (module.js:</span>459:10<span style="color: rgba(0, 0, 0, 1)">)
at Module.load (module.js:</span>348:31<span style="color: rgba(0, 0, 0, 1)">)
at Function._load (module.js:</span>308:12<span style="color: rgba(0, 0, 0, 1)">)
at Array.</span>0 (module.js:479:10<span style="color: rgba(0, 0, 0, 1)">)
at EventEmitter._tickCallback (node.js:</span>192:40)</pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p> </p>
<h2>util.inspect</h2>
<p><span class="marked">util.inspect(object,,,) 是一个将任意对象转换 为字符串的方法,通常用于调试和错误输出。它至少接受一个参数 object,即要转换的对象。</span></p>
<p>showHidden 是一个可选参数,如果值为 true,将会输出更多隐藏信息。</p>
<p>depth 表示最大递归的层数,如果对象很复杂,你可以指定层数以控制输出信息的多 少。如果不指定depth,默认会递归2层,指定为 null 表示将不限递归层数完整遍历对象。 如果color 值为 true,输出格式将会以ANSI 颜色编码,通常用于在终端显示更漂亮 的效果。</p>
<p>特别要指出的是,util.inspect 并不会简单地直接把对象转换为字符串,即使该对 象定义了 toString 方法也不会调用。</p>
<div class="cnblogs_code"><img id="code_img_closed_10da116e-4789-4dd5-be9f-ab1303154a91" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_10da116e-4789-4dd5-be9f-ab1303154a91" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_10da116e-4789-4dd5-be9f-ab1303154a91" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> util = require('util'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> Person() {
</span><span style="color: rgba(0, 0, 255, 1)">this</span>.name = 'byvoid'<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">this</span>.toString = <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">() {
</span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.name;
};
}
</span><span style="color: rgba(0, 0, 255, 1)">var</span> obj = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Person();
console.log(util.inspect(obj));
console.log(util.inspect(obj, </span><span style="color: rgba(0, 0, 255, 1)">true</span>));</pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p> </p>
<p>运行结果是:</p>
<div class="cnblogs_code"><img id="code_img_closed_705ab860-e782-4a10-8bdd-95e155cc9d11" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_705ab860-e782-4a10-8bdd-95e155cc9d11" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_705ab860-e782-4a10-8bdd-95e155cc9d11" class="cnblogs_code_hide">
<pre>Person { name: 'byvoid'<span style="color: rgba(0, 0, 0, 1)">, toString: }
Person {
name: </span>'byvoid'<span style="color: rgba(0, 0, 0, 1)">,
toString:
{
: </span>0<span style="color: rgba(0, 0, 0, 1)">,
: </span>''<span style="color: rgba(0, 0, 0, 1)">,
: </span><span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">,
: </span><span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">,
: { : } } }</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p> </p>
<h2>util.isArray(object)</h2>
<p>如果给定的参数 "object" 是一个数组返回true,否则返回false。</p>
<div class="cnblogs_code"><img id="code_img_closed_a17c9b83-08f4-4c25-9f6d-63d777e31da1" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_a17c9b83-08f4-4c25-9f6d-63d777e31da1" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_a17c9b83-08f4-4c25-9f6d-63d777e31da1" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> util = require('util'<span style="color: rgba(0, 0, 0, 1)">);
util.isArray([])
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> true</span>
util.isArray(<span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Array)
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> true</span>
<span style="color: rgba(0, 0, 0, 1)">util.isArray({})
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> false</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p> </p>
<h2>util.isRegExp(object)</h2>
<p>如果给定的参数 "object" 是一个正则表达式返回true,否则返回false。</p>
<div class="cnblogs_code"><img id="code_img_closed_55631d4d-92e0-49a8-b82e-b0ff7ab7d019" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_55631d4d-92e0-49a8-b82e-b0ff7ab7d019" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_55631d4d-92e0-49a8-b82e-b0ff7ab7d019" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> util = require('util'<span style="color: rgba(0, 0, 0, 1)">);
util.isRegExp(</span>/some regexp/<span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> true</span>
util.isRegExp(<span style="color: rgba(0, 0, 255, 1)">new</span> RegExp('another regexp'<span style="color: rgba(0, 0, 0, 1)">))
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> true</span>
<span style="color: rgba(0, 0, 0, 1)">util.isRegExp({})
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> false</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p> </p>
<h2>util.isDate(object)</h2>
<p>如果给定的参数 "object" 是一个日期返回true,否则返回false。</p>
<div class="cnblogs_code"><img id="code_img_closed_30c328e0-c6c0-4bfc-93f6-299745658f0e" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_30c328e0-c6c0-4bfc-93f6-299745658f0e" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_30c328e0-c6c0-4bfc-93f6-299745658f0e" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> util = require('util'<span style="color: rgba(0, 0, 0, 1)">);
util.isDate(</span><span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Date())
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> true</span>
<span style="color: rgba(0, 0, 0, 1)">util.isDate(Date())
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> false (without 'new' returns a String)</span>
<span style="color: rgba(0, 0, 0, 1)">util.isDate({})
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> false</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p> </p>
<h2>util.isError(object)</h2>
<p>如果给定的参数 "object" 是一个错误对象返回true,否则返回false。</p>
<div class="cnblogs_code"><img id="code_img_closed_ad9611ab-5c9d-4426-9ef4-334d0065d6b1" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_ad9611ab-5c9d-4426-9ef4-334d0065d6b1" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_ad9611ab-5c9d-4426-9ef4-334d0065d6b1" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> util = require('util'<span style="color: rgba(0, 0, 0, 1)">);
util.isError(</span><span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Error())
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> true</span>
util.isError(<span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> TypeError())
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> true</span>
util.isError({ name: 'Error', message: 'an error occurred'<span style="color: rgba(0, 0, 0, 1)"> })
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> false</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<h1>Node.js 文件系统</h1>
<p>Node.js 提供一组类似 UNIX(POSIX)标准的文件操作API。 Node 导入文件系统模块(fs)语法如下所示:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> fs = require("fs")</pre>
</div>
<p> </p>
<h2>异步和同步</h2>
<p>Node.js 文件系统(fs 模块)模块中的方法均有异步和同步版本,例如读取文件内容的函数有异步的 fs.readFile() 和同步的 fs.readFileSync()。</p>
<p>异步的方法函数最后一个参数为回调函数,回调函数的第一个参数包含了错误信息(error)。</p>
<p>建议大家使用异步方法,比起同步,异步方法性能更高,速度更快,而且没有阻塞。</p>
<h3>实例</h3>
<p>创建 input.txt 文件,内容如下:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">菜鸟教程官网地址:www.runoob.com
文件读取实例</span></pre>
</div>
<p> </p>
<p>创建 file.js 文件, 代码如下:</p>
<div class="cnblogs_code"><img id="code_img_closed_bc05be0d-6b98-490a-898e-9433fe81044e" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_bc05be0d-6b98-490a-898e-9433fe81044e" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_bc05be0d-6b98-490a-898e-9433fe81044e" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> fs = require("fs"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 异步读取</span>
fs.readFile('input.txt', <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> (err, data) {
</span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (err) {
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> console.error(err);
}
console.log(</span>"异步读取: " +<span style="color: rgba(0, 0, 0, 1)"> data.toString());
});
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 同步读取</span>
<span style="color: rgba(0, 0, 255, 1)">var</span> data = fs.readFileSync('input.txt'<span style="color: rgba(0, 0, 0, 1)">);
console.log(</span>"同步读取: " +<span style="color: rgba(0, 0, 0, 1)"> data.toString());
console.log(</span>"程序执行完毕。");</pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p> </p>
<p>以上代码执行结果如下:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">$ node file.js
同步读取: 菜鸟教程官网地址:www.runoob.com
文件读取实例
程序执行完毕。
异步读取: 菜鸟教程官网地址:www.runoob.com
文件读取实例</span></pre>
</div>
<p> </p>
<p>接下来,让我们来具体了解下 Node.js 文件系统的方法。</p>
<h2>打开文件</h2>
<h3>语法</h3>
<p>以下为在异步模式下打开文件的语法格式:</p>
<div class="cnblogs_code">
<pre>fs.open(path, flags[, mode], callback)</pre>
</div>
<p> </p>
<h3>参数</h3>
<p>参数使用说明如下:</p>
<ul>
<li>
<p><strong>path</strong> - 文件的路径。</p>
</li>
<li>
<p><strong>flags</strong> - 文件打开的行为。具体值详见下文。</p>
</li>
<li>
<p><strong>mode</strong> - 设置文件模式(权限),文件创建默认权限为 0666(可读,可写)。</p>
</li>
<li>
<p><strong>callback</strong> - 回调函数,带有两个参数如:callback(err, fd)。</p>
</li>
</ul>
<p>flags 参数可以是以下值:</p>
<table class="reference">
<tbody>
<tr><th>Flag</th><th>描述</th></tr>
<tr>
<td>r</td>
<td>以读取模式打开文件。如果文件不存在抛出异常。</td>
</tr>
<tr>
<td>r+</td>
<td>以读写模式打开文件。如果文件不存在抛出异常。</td>
</tr>
<tr>
<td>rs</td>
<td>以同步的方式读取文件。</td>
</tr>
<tr>
<td>rs+</td>
<td>以同步的方式读取和写入文件。</td>
</tr>
<tr>
<td>w</td>
<td>以写入模式打开文件,如果文件不存在则创建。</td>
</tr>
<tr>
<td>wx</td>
<td>类似 'w',但是如果文件路径存在,则文件写入失败。</td>
</tr>
<tr>
<td>w+</td>
<td>以读写模式打开文件,如果文件不存在则创建。</td>
</tr>
<tr>
<td>wx+</td>
<td>类似 'w+', 但是如果文件路径存在,则文件读写失败。</td>
</tr>
<tr>
<td>a</td>
<td>以追加模式打开文件,如果文件不存在则创建。</td>
</tr>
<tr>
<td>ax</td>
<td>类似 'a', 但是如果文件路径存在,则文件追加失败。</td>
</tr>
<tr>
<td>a+</td>
<td>以读取追加模式打开文件,如果文件不存在则创建。</td>
</tr>
<tr>
<td>ax+</td>
<td>类似 'a+', 但是如果文件路径存在,则文件读取追加失败。</td>
</tr>
</tbody>
</table>
<h3>实例</h3>
<p>接下来我们创建 file.js 文件,并打开 input.txt 文件进行读写,代码如下所示:</p>
<div class="cnblogs_code"><img id="code_img_closed_07affb55-8140-4c36-9462-9ac58121986b" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_07affb55-8140-4c36-9462-9ac58121986b" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_07affb55-8140-4c36-9462-9ac58121986b" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> fs = require("fs"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 异步打开文件</span>
console.log("准备打开文件!"<span style="color: rgba(0, 0, 0, 1)">);
fs.open(</span>'input.txt', 'r+', <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(err, fd) {
</span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (err) {
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> console.error(err);
}
console.log(</span>"文件打开成功!"<span style="color: rgba(0, 0, 0, 1)">);
});</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p> </p>
<p>以上代码执行结果如下:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">$ node file.js
准备打开文件!
文件打开成功!</span></pre>
</div>
<p> </p>
<h2>获取文件信息</h2>
<h3>语法</h3>
<p>以下为通过异步模式获取文件信息的语法格式:</p>
<div class="cnblogs_code">
<pre>fs.stat(path, callback)</pre>
</div>
<p> </p>
<h3>参数</h3>
<p>参数使用说明如下:</p>
<ul>
<li>
<p><strong>path</strong> - 文件路径。</p>
</li>
<li>
<p><strong>callback</strong> - 回调函数,带有两个参数如:(err, stats), <strong>stats</strong> 是 fs.Stats 对象。</p>
</li>
</ul>
<p>fs.stat(path)执行后,会将stats类的实例返回给其回调函数。可以通过stats类中的提供方法判断文件的相关属性。例如判断是否为文件:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> fs = require('fs'<span style="color: rgba(0, 0, 0, 1)">);
fs.stat(</span>'/Users/liuht/code/itbilu/demo/fs.js', <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> (err, stats) {
console.log(stats.isFile()); </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">true</span>
})</pre>
</div>
<p> </p>
<p>stats类中的方法有:</p>
<table class="reference">
<tbody>
<tr><th>方法</th><th>描述</th></tr>
<tr>
<td>stats.isFile()</td>
<td>如果是文件返回 true,否则返回 false。</td>
</tr>
<tr>
<td>stats.isDirectory()</td>
<td>如果是目录返回 true,否则返回 false。</td>
</tr>
<tr>
<td>stats.isBlockDevice()</td>
<td>如果是块设备返回 true,否则返回 false。</td>
</tr>
<tr>
<td>stats.isCharacterDevice()</td>
<td>如果是字符设备返回 true,否则返回 false。</td>
</tr>
<tr>
<td>stats.isSymbolicLink()</td>
<td>如果是软链接返回 true,否则返回 false。</td>
</tr>
<tr>
<td>stats.isFIFO()</td>
<td>如果是FIFO,返回true,否则返回 false。FIFO是UNIX中的一种特殊类型的命令管道。</td>
</tr>
<tr>
<td>stats.isSocket()</td>
<td>如果是 Socket 返回 true,否则返回 false。</td>
</tr>
</tbody>
</table>
<h3>实例</h3>
<p>接下来我们创建 file.js 文件,代码如下所示:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> fs = require("fs"<span style="color: rgba(0, 0, 0, 1)">);
console.log(</span>"准备打开文件!"<span style="color: rgba(0, 0, 0, 1)">);
fs.stat(</span>'input.txt', <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> (err, stats) {
</span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (err) {
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> console.error(err);
}
console.log(stats);
console.log(</span>"读取文件信息成功!"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 检测文件类型</span>
console.log("是否为文件(isFile) ? " +<span style="color: rgba(0, 0, 0, 1)"> stats.isFile());
console.log(</span>"是否为目录(isDirectory) ? " +<span style="color: rgba(0, 0, 0, 1)"> stats.isDirectory());
});</span></pre>
</div>
<p> </p>
<p>以上代码执行结果如下:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">$ node file.js
准备打开文件!
{ dev: </span>16777220<span style="color: rgba(0, 0, 0, 1)">,
mode: </span>33188<span style="color: rgba(0, 0, 0, 1)">,
nlink: </span>1<span style="color: rgba(0, 0, 0, 1)">,
uid: </span>501<span style="color: rgba(0, 0, 0, 1)">,
gid: </span>20<span style="color: rgba(0, 0, 0, 1)">,
rdev: </span>0<span style="color: rgba(0, 0, 0, 1)">,
blksize: </span>4096<span style="color: rgba(0, 0, 0, 1)">,
ino: </span>40333161<span style="color: rgba(0, 0, 0, 1)">,
size: </span>61<span style="color: rgba(0, 0, 0, 1)">,
blocks: </span>8<span style="color: rgba(0, 0, 0, 1)">,
atime: Mon Sep </span>07 2015 17:43:55 GMT+0800<span style="color: rgba(0, 0, 0, 1)"> (CST),
mtime: Mon Sep </span>07 2015 17:22:35 GMT+0800<span style="color: rgba(0, 0, 0, 1)"> (CST),
ctime: Mon Sep </span>07 2015 17:22:35 GMT+0800<span style="color: rgba(0, 0, 0, 1)"> (CST) }
读取文件信息成功!
是否为文件(isFile) </span>? <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">
是否为目录(isDirectory) </span>? <span style="color: rgba(0, 0, 255, 1)">false</span></pre>
</div>
<p> </p>
<h2>写入文件</h2>
<h3>语法</h3>
<p>以下为异步模式下写入文件的语法格式:</p>
<div class="cnblogs_code">
<pre>fs.writeFile(file, data[, options], callback)</pre>
</div>
<p> </p>
<p>writeFile 直接打开文件默认是 <span class="marked">w 模式,所以如果文件存在,该方法写入的内容会覆盖旧的文件内容。</span></p>
<h3>参数</h3>
<p>参数使用说明如下:</p>
<ul>
<li>
<p><strong>file</strong> - 文件名或文件描述符。</p>
</li>
<li>
<p><strong>data</strong> - 要写入文件的数据,可以是 String(字符串) 或 Buffer(缓冲) 对象。</p>
</li>
<li>
<p><strong>options</strong> - 该参数是一个对象,包含 {encoding, mode, flag}。默认编码为 utf8, 模式为 0666 , flag 为 'w'</p>
</li>
<li>
<p><strong>callback</strong> - 回调函数,回调函数只包含错误信息参数(err),在写入失败时返回。</p>
</li>
</ul>
<h3>实例</h3>
<p>接下来我们创建 file.js 文件,代码如下所示:</p>
<div class="cnblogs_code"><img id="code_img_closed_7b09e892-07c8-4abc-b051-453ae1e1a0fa" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_7b09e892-07c8-4abc-b051-453ae1e1a0fa" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_7b09e892-07c8-4abc-b051-453ae1e1a0fa" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> fs = require("fs"<span style="color: rgba(0, 0, 0, 1)">);
console.log(</span>"准备写入文件"<span style="color: rgba(0, 0, 0, 1)">);
fs.writeFile(</span>'input.txt', '我是通 过fs.writeFile 写入文件的内容',<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(err) {
</span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (err) {
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> console.error(err);
}
console.log(</span>"数据写入成功!"<span style="color: rgba(0, 0, 0, 1)">);
console.log(</span>"--------我是分割线-------------"<span style="color: rgba(0, 0, 0, 1)">)
console.log(</span>"读取写入的数据!"<span style="color: rgba(0, 0, 0, 1)">);
fs.readFile(</span>'input.txt', <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> (err, data) {
</span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (err) {
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> console.error(err);
}
console.log(</span>"异步读取文件数据: " +<span style="color: rgba(0, 0, 0, 1)"> data.toString());
});
});</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p> </p>
<p>以上代码执行结果如下:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">$ node file.js
准备写入文件
数据写入成功!
</span>--------我是分割线-------------<span style="color: rgba(0, 0, 0, 1)">
读取写入的数据!
异步读取文件数据: 我是通 过fs.writeFile 写入文件的内容</span></pre>
</div>
<p> </p>
<h2>读取文件</h2>
<h3>语法</h3>
<p>以下为异步模式下读取文件的语法格式:</p>
<div class="cnblogs_code">
<pre>fs.read(fd, buffer, offset, length, position, callback)</pre>
</div>
<p> </p>
<p>该方法使用了文件描述符来读取文件。</p>
<h3>参数</h3>
<p>参数使用说明如下:</p>
<ul>
<li>
<p><strong>fd</strong> - 通过 fs.open() 方法返回的文件描述符。</p>
</li>
<li>
<p><strong>buffer</strong> - 数据写入的缓冲区。</p>
</li>
<li>
<p><strong>offset</strong> - 缓冲区写入的写入偏移量。</p>
</li>
<li>
<p><strong>length</strong> - 要从文件中读取的字节数。</p>
</li>
<li>
<p><strong>position</strong> - 文件读取的起始位置,如果 position 的值为 null,则会从当前文件指针的位置读取。</p>
</li>
<li>
<p><strong>callback</strong> - 回调函数,有三个参数err, bytesRead, buffer,err 为错误信息, bytesRead 表示读取的字节数,buffer 为缓冲区对象。</p>
</li>
</ul>
<h3>实例</h3>
<p>input.txt 文件内容为:</p>
<div class="cnblogs_code">
<pre>菜鸟教程官网地址:www.runoob.com</pre>
</div>
<p> </p>
<p>接下来我们创建 file.js 文件,代码如下所示:</p>
<div class="cnblogs_code"><img id="code_img_closed_39dc6766-c5e1-438e-88f4-9eac0ba0ee68" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_39dc6766-c5e1-438e-88f4-9eac0ba0ee68" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_39dc6766-c5e1-438e-88f4-9eac0ba0ee68" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> fs = require("fs"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> buf = <span style="color: rgba(0, 0, 255, 1)">new</span> Buffer.alloc(1024<span style="color: rgba(0, 0, 0, 1)">);
console.log(</span>"准备打开已存在的文件!"<span style="color: rgba(0, 0, 0, 1)">);
fs.open(</span>'input.txt', 'r+', <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(err, fd) {
</span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (err) {
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> console.error(err);
}
console.log(</span>"文件打开成功!"<span style="color: rgba(0, 0, 0, 1)">);
console.log(</span>"准备读取文件:"<span style="color: rgba(0, 0, 0, 1)">);
fs.read(fd, buf, </span>0, buf.length, 0, <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(err, bytes){
</span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (err){
console.log(err);
}
console.log(bytes </span>+ "字节被读取"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 仅输出读取的字节</span>
<span style="color: rgba(0, 0, 255, 1)">if</span>(bytes > 0<span style="color: rgba(0, 0, 0, 1)">){
console.log(buf.slice(</span>0<span style="color: rgba(0, 0, 0, 1)">, bytes).toString());
}
});
});</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p> </p>
<p>以上代码执行结果如下:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">$ node file.js
准备打开已存在的文件!
文件打开成功!
准备读取文件:
</span>42<span style="color: rgba(0, 0, 0, 1)">字节被读取
菜鸟教程官网地址:www.runoob.com</span></pre>
</div>
<p> </p>
<h2>关闭文件</h2>
<h3>语法</h3>
<p>以下为异步模式下关闭文件的语法格式:</p>
<div class="cnblogs_code">
<pre>fs.close(fd, callback)</pre>
</div>
<p> </p>
<p>该方法使用了文件描述符来读取文件。</p>
<h3>参数</h3>
<p>参数使用说明如下:</p>
<ul>
<li>
<p><strong>fd</strong> - 通过 fs.open() 方法返回的文件描述符。</p>
</li>
<li>
<p><strong>callback</strong> - 回调函数,没有参数。</p>
</li>
</ul>
<h3>实例</h3>
<p>input.txt 文件内容为:</p>
<div class="cnblogs_code">
<pre>菜鸟教程官网地址:www.runoob.com</pre>
</div>
<p> </p>
<p>接下来我们创建 file.js 文件,代码如下所示:</p>
<div class="cnblogs_code"><img id="code_img_closed_e56a5a61-0290-4bde-81c4-823a52b664d0" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_e56a5a61-0290-4bde-81c4-823a52b664d0" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_e56a5a61-0290-4bde-81c4-823a52b664d0" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> fs = require("fs"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> buf = <span style="color: rgba(0, 0, 255, 1)">new</span> Buffer.alloc(1024<span style="color: rgba(0, 0, 0, 1)">);
console.log(</span>"准备打开文件!"<span style="color: rgba(0, 0, 0, 1)">);
fs.open(</span>'input.txt', 'r+', <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(err, fd) {
</span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (err) {
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> console.error(err);
}
console.log(</span>"文件打开成功!"<span style="color: rgba(0, 0, 0, 1)">);
console.log(</span>"准备读取文件!"<span style="color: rgba(0, 0, 0, 1)">);
fs.read(fd, buf, </span>0, buf.length, 0, <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(err, bytes){
</span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (err){
console.log(err);
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 仅输出读取的字节</span>
<span style="color: rgba(0, 0, 255, 1)">if</span>(bytes > 0<span style="color: rgba(0, 0, 0, 1)">){
console.log(buf.slice(</span>0<span style="color: rgba(0, 0, 0, 1)">, bytes).toString());
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 关闭文件</span>
fs.close(fd, <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(err){
</span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (err){
console.log(err);
}
console.log(</span>"文件关闭成功"<span style="color: rgba(0, 0, 0, 1)">);
});
});
});</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p> </p>
<p>以上代码执行结果如下:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">$ node file.js
准备打开文件!
文件打开成功!
准备读取文件!
菜鸟教程官网地址:www.runoob.com
文件关闭成功</span></pre>
</div>
<p> </p>
<h2>截取文件</h2>
<h3>语法</h3>
<p>以下为异步模式下截取文件的语法格式:</p>
<div class="cnblogs_code">
<pre>fs.ftruncate(fd, len, callback)</pre>
</div>
<p> </p>
<p>该方法使用了文件描述符来读取文件。</p>
<h3>参数</h3>
<p>参数使用说明如下:</p>
<ul>
<li>
<p><strong>fd</strong> - 通过 fs.open() 方法返回的文件描述符。</p>
</li>
<li>
<p><strong>len</strong> - 文件内容截取的长度。</p>
</li>
<li>
<p><strong>callback</strong> - 回调函数,没有参数。</p>
</li>
</ul>
<h3>实例</h3>
<p>input.txt 文件内容为:</p>
<div class="cnblogs_code">
<pre>site:www.runoob.com</pre>
</div>
<p> </p>
<p>接下来我们创建 file.js 文件,代码如下所示:</p>
<div class="cnblogs_code"><img id="code_img_closed_0078a134-534e-4ace-bf2f-2385f7790a05" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_0078a134-534e-4ace-bf2f-2385f7790a05" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_0078a134-534e-4ace-bf2f-2385f7790a05" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> fs = require("fs"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> buf = <span style="color: rgba(0, 0, 255, 1)">new</span> Buffer.alloc(1024<span style="color: rgba(0, 0, 0, 1)">);
console.log(</span>"准备打开文件!"<span style="color: rgba(0, 0, 0, 1)">);
fs.open(</span>'input.txt', 'r+', <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(err, fd) {
</span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (err) {
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> console.error(err);
}
console.log(</span>"文件打开成功!"<span style="color: rgba(0, 0, 0, 1)">);
console.log(</span>"截取10字节内的文件内容,超出部分将被去除。"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 截取文件</span>
fs.ftruncate(fd, 10, <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(err){
</span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (err){
console.log(err);
}
console.log(</span>"文件截取成功。"<span style="color: rgba(0, 0, 0, 1)">);
console.log(</span>"读取相同的文件"<span style="color: rgba(0, 0, 0, 1)">);
fs.read(fd, buf, </span>0, buf.length, 0, <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(err, bytes){
</span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (err){
console.log(err);
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 仅输出读取的字节</span>
<span style="color: rgba(0, 0, 255, 1)">if</span>(bytes > 0<span style="color: rgba(0, 0, 0, 1)">){
console.log(buf.slice(</span>0<span style="color: rgba(0, 0, 0, 1)">, bytes).toString());
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 关闭文件</span>
fs.close(fd, <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(err){
</span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (err){
console.log(err);
}
console.log(</span>"文件关闭成功!"<span style="color: rgba(0, 0, 0, 1)">);
});
});
});
});</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p> </p>
<p>以上代码执行结果如下:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">$ node file.js
准备打开文件!
文件打开成功!
截取10字节内的文件内容,超出部分将被去除。
文件截取成功。
读取相同的文件
site:www.r
文件关闭成功</span></pre>
</div>
<p> </p>
<h2>删除文件</h2>
<h3>语法</h3>
<p>以下为删除文件的语法格式:</p>
<div class="cnblogs_code">
<pre>fs.unlink(path, callback)</pre>
</div>
<p> </p>
<h3>参数</h3>
<p>参数使用说明如下:</p>
<ul>
<li>
<p><strong>path</strong> - 文件路径。</p>
</li>
<li>
<p><strong>callback</strong> - 回调函数,没有参数。</p>
</li>
</ul>
<h3>实例</h3>
<p>input.txt 文件内容为:</p>
<div class="cnblogs_code">
<pre>site:www.runoob.com</pre>
</div>
<p> </p>
<p>接下来我们创建 file.js 文件,代码如下所示:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> fs = require("fs"<span style="color: rgba(0, 0, 0, 1)">);
console.log(</span>"准备删除文件!"<span style="color: rgba(0, 0, 0, 1)">);
fs.unlink(</span>'input.txt', <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(err) {
</span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (err) {
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> console.error(err);
}
console.log(</span>"文件删除成功!"<span style="color: rgba(0, 0, 0, 1)">);
});</span></pre>
</div>
<p> </p>
<p>以上代码执行结果如下:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">$ node file.js
准备删除文件!
文件删除成功!</span></pre>
</div>
<p> </p>
<p>再去查看 input.txt 文件,发现已经不存在了。</p>
<h2>创建目录</h2>
<h3>语法</h3>
<p>以下为创建目录的语法格式:</p>
<div class="cnblogs_code">
<pre>fs.mkdir(path[, options], callback)</pre>
</div>
<p> </p>
<h3>参数</h3>
<p>参数使用说明如下:</p>
<ul>
<li>
<p><strong>path</strong> - 文件路径。</p>
</li>
<li>
<p>options 参数可以是:</p>
<ul>
<li><strong>recursive </strong>- 是否以递归的方式创建目录,默认为 false。</li>
<li><strong>mode</strong> - 设置目录权限,默认为 0777。</li>
</ul>
</li>
<li>
<p><strong>callback</strong> - 回调函数,没有参数。</p>
</li>
</ul>
<h3>实例</h3>
<p>接下来我们创建 file.js 文件,代码如下所示:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> fs = require("fs"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> tmp 目录必须存在</span>
console.log("创建目录 /tmp/test/"<span style="color: rgba(0, 0, 0, 1)">);
fs.mkdir(</span>"/tmp/test/",<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(err){
</span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (err) {
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> console.error(err);
}
console.log(</span>"目录创建成功。"<span style="color: rgba(0, 0, 0, 1)">);
});</span></pre>
</div>
<p> </p>
<p>以上代码执行结果如下:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">$ node file.js
创建目录 </span>/tmp/test/<span style="color: rgba(0, 0, 0, 1)">
目录创建成功。</span></pre>
</div>
<p> </p>
<p>可以添加 recursive: true 参数,不管创建的目录 /tmp 和 /tmp/a 是否存在:</p>
<div class="cnblogs_code">
<pre>fs.mkdir('/tmp/a/apple', { recursive: <span style="color: rgba(0, 0, 255, 1)">true</span> }, (err) =><span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (err) <span style="color: rgba(0, 0, 255, 1)">throw</span><span style="color: rgba(0, 0, 0, 1)"> err;
});</span></pre>
</div>
<p> </p>
<h2>读取目录</h2>
<h3>语法</h3>
<p>以下为读取目录的语法格式:</p>
<div class="cnblogs_code">
<pre>fs.readdir(path, callback)</pre>
</div>
<p> </p>
<h3>参数</h3>
<p>参数使用说明如下:</p>
<ul>
<li>
<p><strong>path</strong> - 文件路径。</p>
</li>
<li>
<p><strong>callback</strong> - 回调函数,回调函数带有两个参数err, files,err 为错误信息,files 为 目录下的文件数组列表。</p>
</li>
</ul>
<h3>实例</h3>
<p>接下来我们创建 file.js 文件,代码如下所示:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> fs = require("fs"<span style="color: rgba(0, 0, 0, 1)">);
console.log(</span>"查看 /tmp 目录"<span style="color: rgba(0, 0, 0, 1)">);
fs.readdir(</span>"/tmp/",<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(err, files){
</span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (err) {
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> console.error(err);
}
files.forEach( </span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> (file){
console.log( file );
});
});</span></pre>
</div>
<p> </p>
<p>以上代码执行结果如下:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">$ node file.js
查看 </span>/tmp 目录
<span style="color: rgba(0, 0, 0, 1)">input.out
output.out
test
test.txt</span></pre>
</div>
<p> </p>
<h2>删除目录</h2>
<h3>语法</h3>
<p>以下为删除目录的语法格式:</p>
<div class="cnblogs_code">
<pre>fs.rmdir(path, callback)</pre>
</div>
<p> </p>
<h3>参数</h3>
<p>参数使用说明如下:</p>
<ul>
<li>
<p><strong>path</strong> - 文件路径。</p>
</li>
<li>
<p><strong>callback</strong> - 回调函数,没有参数。</p>
</li>
</ul>
<h3>实例</h3>
<p>接下来我们创建 file.js 文件,代码如下所示:</p>
<div class="cnblogs_code"><img id="code_img_closed_67773973-6cf7-4185-8a76-00f20aef997d" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_67773973-6cf7-4185-8a76-00f20aef997d" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_67773973-6cf7-4185-8a76-00f20aef997d" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> fs = require("fs"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 执行前创建一个空的 /tmp/test 目录</span>
console.log("准备删除目录 /tmp/test"<span style="color: rgba(0, 0, 0, 1)">);
fs.rmdir(</span>"/tmp/test",<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(err){
</span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (err) {
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> console.error(err);
}
console.log(</span>"读取 /tmp 目录"<span style="color: rgba(0, 0, 0, 1)">);
fs.readdir(</span>"/tmp/",<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(err, files){
</span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (err) {
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> console.error(err);
}
files.forEach( </span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> (file){
console.log( file );
});
});
});</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p> </p>
<p>以上代码执行结果如下:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">$ node file.js
准备删除目录 </span>/tmp/<span style="color: rgba(0, 0, 0, 1)">test
读取 </span>/tmp 目录
……</pre>
</div>
<p> </p>
<h2>文件模块方法参考手册</h2>
<p>以下为 Node.js 文件模块相同的方法列表:</p>
<table class="reference">
<tbody>
<tr><th>序号</th><th>方法 & 描述</th></tr>
<tr>
<td>1</td>
<td><strong>fs.rename(oldPath, newPath, callback)</strong><br>异步 rename().回调函数没有参数,但可能抛出异常。</td>
</tr>
<tr>
<td>2</td>
<td><strong>fs.ftruncate(fd, len, callback)</strong><br>异步 ftruncate().回调函数没有参数,但可能抛出异常。</td>
</tr>
<tr>
<td>3</td>
<td><strong>fs.ftruncateSync(fd, len)</strong><br>同步 ftruncate()</td>
</tr>
<tr>
<td>4</td>
<td><strong>fs.truncate(path, len, callback)</strong><br>异步 truncate().回调函数没有参数,但可能抛出异常。</td>
</tr>
<tr>
<td>5</td>
<td><strong>fs.truncateSync(path, len)</strong><br>同步 truncate()</td>
</tr>
<tr>
<td>6</td>
<td><strong>fs.chown(path, uid, gid, callback)</strong><br>异步 chown().回调函数没有参数,但可能抛出异常。</td>
</tr>
<tr>
<td>7</td>
<td><strong>fs.chownSync(path, uid, gid)</strong><br>同步 chown()</td>
</tr>
<tr>
<td>8</td>
<td><strong>fs.fchown(fd, uid, gid, callback)</strong><br>异步 fchown().回调函数没有参数,但可能抛出异常。</td>
</tr>
<tr>
<td>9</td>
<td><strong>fs.fchownSync(fd, uid, gid)</strong><br>同步 fchown()</td>
</tr>
<tr>
<td>10</td>
<td><strong>fs.lchown(path, uid, gid, callback)</strong><br>异步 lchown().回调函数没有参数,但可能抛出异常。</td>
</tr>
<tr>
<td>11</td>
<td><strong>fs.lchownSync(path, uid, gid)</strong><br>同步 lchown()</td>
</tr>
<tr>
<td>12</td>
<td><strong>fs.chmod(path, mode, callback)</strong><br>异步 chmod().回调函数没有参数,但可能抛出异常。</td>
</tr>
<tr>
<td>13</td>
<td><strong>fs.chmodSync(path, mode)</strong><br>同步 chmod().</td>
</tr>
<tr>
<td>14</td>
<td><strong>fs.fchmod(fd, mode, callback)</strong><br>异步 fchmod().回调函数没有参数,但可能抛出异常。</td>
</tr>
<tr>
<td>15</td>
<td><strong>fs.fchmodSync(fd, mode)</strong><br>同步 fchmod().</td>
</tr>
<tr>
<td>16</td>
<td><strong>fs.lchmod(path, mode, callback)</strong><br>异步 lchmod().回调函数没有参数,但可能抛出异常。Only available on Mac OS X.</td>
</tr>
<tr>
<td>17</td>
<td><strong>fs.lchmodSync(path, mode)</strong><br>同步 lchmod().</td>
</tr>
<tr>
<td>18</td>
<td><strong>fs.stat(path, callback)</strong><br>异步 stat(). 回调函数有两个参数 err, stats,stats 是 fs.Stats 对象。</td>
</tr>
<tr>
<td>19</td>
<td><strong>fs.lstat(path, callback)</strong><br>异步 lstat(). 回调函数有两个参数 err, stats,stats 是 fs.Stats 对象。</td>
</tr>
<tr>
<td>20</td>
<td><strong>fs.fstat(fd, callback)</strong><br>异步 fstat(). 回调函数有两个参数 err, stats,stats 是 fs.Stats 对象。</td>
</tr>
<tr>
<td>21</td>
<td><strong>fs.statSync(path)</strong><br>同步 stat(). 返回 fs.Stats 的实例。</td>
</tr>
<tr>
<td>22</td>
<td><strong>fs.lstatSync(path)</strong><br>同步 lstat(). 返回 fs.Stats 的实例。</td>
</tr>
<tr>
<td>23</td>
<td><strong>fs.fstatSync(fd)</strong><br>同步 fstat(). 返回 fs.Stats 的实例。</td>
</tr>
<tr>
<td>24</td>
<td><strong>fs.link(srcpath, dstpath, callback)</strong><br>异步 link().回调函数没有参数,但可能抛出异常。</td>
</tr>
<tr>
<td>25</td>
<td><strong>fs.linkSync(srcpath, dstpath)</strong><br>同步 link().</td>
</tr>
<tr>
<td>26</td>
<td><strong>fs.symlink(srcpath, dstpath[, type], callback)</strong><br>异步 symlink().回调函数没有参数,但可能抛出异常。 type 参数可以设置为 'dir', 'file', 或 'junction' (默认为 'file') 。</td>
</tr>
<tr>
<td>27</td>
<td><strong>fs.symlinkSync(srcpath, dstpath[, type])</strong><br>同步 symlink().</td>
</tr>
<tr>
<td>28</td>
<td><strong>fs.readlink(path, callback)</strong><br>异步 readlink(). 回调函数有两个参数 err, linkString。</td>
</tr>
<tr>
<td>29</td>
<td><strong>fs.realpath(path[, cache], callback)</strong><br>异步 realpath(). 回调函数有两个参数 err, resolvedPath。</td>
</tr>
<tr>
<td>30</td>
<td><strong>fs.realpathSync(path[, cache])</strong><br>同步 realpath()。返回绝对路径。</td>
</tr>
<tr>
<td>31</td>
<td><strong>fs.unlink(path, callback)</strong><br>异步 unlink().回调函数没有参数,但可能抛出异常。</td>
</tr>
<tr>
<td>32</td>
<td><strong>fs.unlinkSync(path)</strong><br>同步 unlink().</td>
</tr>
<tr>
<td>33</td>
<td><strong>fs.rmdir(path, callback)</strong><br>异步 rmdir().回调函数没有参数,但可能抛出异常。</td>
</tr>
<tr>
<td>34</td>
<td><strong>fs.rmdirSync(path)</strong><br>同步 rmdir().</td>
</tr>
<tr>
<td>35</td>
<td><strong>fs.mkdir(path[, mode], callback)</strong><br>S异步 mkdir(2).回调函数没有参数,但可能抛出异常。 访问权限默认为 0777。</td>
</tr>
<tr>
<td>36</td>
<td><strong>fs.mkdirSync(path[, mode])</strong><br>同步 mkdir().</td>
</tr>
<tr>
<td>37</td>
<td><strong>fs.readdir(path, callback)</strong><br>异步 readdir(3). 读取目录的内容。</td>
</tr>
<tr>
<td>38</td>
<td><strong>fs.readdirSync(path)</strong><br>同步 readdir().返回文件数组列表。</td>
</tr>
<tr>
<td>39</td>
<td><strong>fs.close(fd, callback)</strong><br>异步 close().回调函数没有参数,但可能抛出异常。</td>
</tr>
<tr>
<td>40</td>
<td><strong>fs.closeSync(fd)</strong><br>同步 close().</td>
</tr>
<tr>
<td>41</td>
<td><strong>fs.open(path, flags[, mode], callback)</strong><br>异步打开文件。</td>
</tr>
<tr>
<td>42</td>
<td><strong>fs.openSync(path, flags[, mode])</strong><br>同步 version of fs.open().</td>
</tr>
<tr>
<td>43</td>
<td><strong>fs.utimes(path, atime, mtime, callback)</strong><br> </td>
</tr>
<tr>
<td>44</td>
<td><strong>fs.utimesSync(path, atime, mtime)</strong><br>修改文件时间戳,文件通过指定的文件路径。</td>
</tr>
<tr>
<td>45</td>
<td><strong>fs.futimes(fd, atime, mtime, callback)</strong><br> </td>
</tr>
<tr>
<td>46</td>
<td><strong>fs.futimesSync(fd, atime, mtime)</strong><br>修改文件时间戳,通过文件描述符指定。</td>
</tr>
<tr>
<td>47</td>
<td><strong>fs.fsync(fd, callback)</strong><br>异步 fsync.回调函数没有参数,但可能抛出异常。</td>
</tr>
<tr>
<td>48</td>
<td><strong>fs.fsyncSync(fd)</strong><br>同步 fsync.</td>
</tr>
<tr>
<td>49</td>
<td><strong>fs.write(fd, buffer, offset, length[, position], callback)</strong><br>将缓冲区内容写入到通过文件描述符指定的文件。</td>
</tr>
<tr>
<td>50</td>
<td><strong>fs.write(fd, data[, position[, encoding]], callback)</strong><br>通过文件描述符 fd 写入文件内容。</td>
</tr>
<tr>
<td>51</td>
<td><strong>fs.writeSync(fd, buffer, offset, length[, position])</strong><br>同步版的 fs.write()。</td>
</tr>
<tr>
<td>52</td>
<td><strong>fs.writeSync(fd, data[, position[, encoding]])</strong><br>同步版的 fs.write().</td>
</tr>
<tr>
<td>53</td>
<td><strong>fs.read(fd, buffer, offset, length, position, callback)</strong><br>通过文件描述符 fd 读取文件内容。</td>
</tr>
<tr>
<td>54</td>
<td><strong>fs.readSync(fd, buffer, offset, length, position)</strong><br>同步版的 fs.read.</td>
</tr>
<tr>
<td>55</td>
<td><strong>fs.readFile(filename[, options], callback)</strong><br>异步读取文件内容。</td>
</tr>
<tr>
<td>56</td>
<td><strong>fs.readFileSync(filename[, options])</strong><br同步版的 fs.readfile.<="" td=""></td>
</tr>
<tr>
<td>57</td>
<td><strong>fs.writeFile(filename, data[, options], callback)</strong><br>异步写入文件内容。</td>
</tr>
<tr>
<td>58</td>
<td><strong>fs.writeFileSync(filename, data[, options])</strong><br>同步版的 fs.writeFile。</td>
</tr>
<tr>
<td>59</td>
<td><strong>fs.appendFile(filename, data[, options], callback)</strong><br>异步追加文件内容。</td>
</tr>
<tr>
<td>60</td>
<td><strong>fs.appendFileSync(filename, data[, options])</strong><br>The 同步 version of fs.appendFile.</td>
</tr>
<tr>
<td>61</td>
<td><strong>fs.watchFile(filename[, options], listener)</strong><br>查看文件的修改。</td>
</tr>
<tr>
<td>62</td>
<td><strong>fs.unwatchFile(filename[, listener])</strong><br>停止查看 filename 的修改。</td>
</tr>
<tr>
<td>63</td>
<td><strong>fs.watch(filename[, options][, listener])</strong><br>查看 filename 的修改,filename 可以是文件或目录。返回 fs.FSWatcher 对象。</td>
</tr>
<tr>
<td>64</td>
<td><strong>fs.exists(path, callback)</strong><br>检测给定的路径是否存在。</td>
</tr>
<tr>
<td>65</td>
<td><strong>fs.existsSync(path)</strong><br>同步版的 fs.exists.</td>
</tr>
<tr>
<td>66</td>
<td><strong>fs.access(path[, mode], callback)</strong><br>测试指定路径用户权限。</td>
</tr>
<tr>
<td>67</td>
<td><strong>fs.accessSync(path[, mode])</strong><br>同步版的 fs.access。</td>
</tr>
<tr>
<td>68</td>
<td><strong>fs.createReadStream(path[, options])</strong><br>返回ReadStream 对象。</td>
</tr>
<tr>
<td>69</td>
<td><strong>fs.createWriteStream(path[, options])</strong><br>返回 WriteStream 对象。</td>
</tr>
<tr>
<td>70</td>
<td><strong>fs.symlink(srcpath, dstpath[, type], callback)</strong><br>异步 symlink().回调函数没有参数,但可能抛出异常。</td>
</tr>
</tbody>
</table>
<p>更多内容,请查看官网文件模块描述:File System。</p>
<p> </p>
<h1>Node.js GET/POST请求</h1>
<p>在很多场景中,我们的服务器都需要跟用户的浏览器打交道,如表单提交。</p>
<p>表单提交到服务器一般都使用 GET/POST 请求。</p>
<p>本章节我们将为大家介绍 Node.js GET/POST请求。</p>
<h2>获取GET请求内容</h2>
<p>由于GET请求直接被嵌入在路径中,URL是完整的请求路径,包括了?后面的部分,因此你可以手动解析后面的内容作为GET请求的参数。</p>
<p>node.js 中 url 模块中的 parse 函数提供了这个功能。</p>
<div class="example">
<h2 class="example">实例</h2>
<div class="example_code">
<div class="hl-main">
<div class="cnblogs_code"><img id="code_img_closed_433cd3bf-11ae-4474-a872-12c9765166c5" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_433cd3bf-11ae-4474-a872-12c9765166c5" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_433cd3bf-11ae-4474-a872-12c9765166c5" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> http = require('http'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> url = require('url'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> util = require('util'<span style="color: rgba(0, 0, 0, 1)">);
http.createServer(</span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(req, res){
res.writeHead(</span>200, {'Content-Type': 'text/plain; charset=utf-8'<span style="color: rgba(0, 0, 0, 1)">});
res.end(util.inspect(url.parse(req.url, </span><span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">)));
}).listen(</span>3000);</pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p> </p>
</div>
</div>
</div>
<p>在浏览器中访问 http://127.0.0.1:3000/user?name=mikey&url=test 然后查看返回结果:</p>
<p><img src="https://img2018.cnblogs.com/blog/1399348/201910/1399348-20191004182213377-707075219.png" alt=""></p>
<p> </p>
<p> </p>
<h2>获取 POST 请求内容</h2>
<p>POST 请求的内容全部的都在请求体中,http.ServerRequest 并没有一个属性内容为请求体,原因是等待请求体传输可能是一件耗时的工作。</p>
<p>比如上传文件,而很多时候我们可能并不需要理会请求体的内容,恶意的POST请求会大大消耗服务器的资源,所以 node.js 默认是不会解析请求体的,当你需要的时候,需要手动来做。</p>
<div class="example">
<h2 class="example">基本语法结构说明</h2>
<div class="example_code">
<div class="hl-main">
<div class="cnblogs_code"><img id="code_img_closed_e5350012-8896-4639-b780-9652f0194707" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_e5350012-8896-4639-b780-9652f0194707" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_e5350012-8896-4639-b780-9652f0194707" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> http = require('http'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> querystring = require('querystring'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> util = require('util'<span style="color: rgba(0, 0, 0, 1)">);
http.createServer(</span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(req, res){
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 定义了一个post变量,用于暂存请求体的信息</span>
<span style="color: rgba(0, 0, 255, 1)">var</span> post = ''<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 通过req的data事件监听函数,每当接受到请求体的数据,就累加到post变量中</span>
req.on('data', <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(chunk){
post </span>+=<span style="color: rgba(0, 0, 0, 1)"> chunk;
});
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 在end事件触发后,通过querystring.parse将post解析为真正的POST请求格式,然后向客户端返回。</span>
req.on('end', <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(){
post </span>=<span style="color: rgba(0, 0, 0, 1)"> querystring.parse(post);
res.end(util.inspect(post));
});
}).listen(</span>3000);</pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
</div>
</div>
</div>
<p>以下实例表单通过 POST 提交并输出数据:</p>
<div class="example">
<h2 class="example">实例</h2>
<div class="example_code">
<div class="hl-main">
<div class="cnblogs_code"><img id="code_img_closed_547bce99-a321-4e61-a913-e9be98a2e6ef" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_547bce99-a321-4e61-a913-e9be98a2e6ef" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_547bce99-a321-4e61-a913-e9be98a2e6ef" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> http = require('http'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> querystring = require('querystring'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> 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>'<span style="color: rgba(0, 0, 0, 1)">;
http.createServer(</span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> (req, res) {
</span><span style="color: rgba(0, 0, 255, 1)">var</span> body = ""<span style="color: rgba(0, 0, 0, 1)">;
req.on(</span>'data', <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> (chunk) {
body </span>+=<span style="color: rgba(0, 0, 0, 1)"> chunk;
});
req.on(</span>'end', <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> () {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 解析参数</span>
body =<span style="color: rgba(0, 0, 0, 1)"> querystring.parse(body);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 设置响应头部信息及编码</span>
res.writeHead(200, {'Content-Type': 'text/html; charset=utf8'<span style="color: rgba(0, 0, 0, 1)">});
</span><span style="color: rgba(0, 0, 255, 1)">if</span>(body.name && body.url) { <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 输出提交的数据</span>
res.write("网站名:" +<span style="color: rgba(0, 0, 0, 1)"> body.name);
res.write(</span>"<br>"<span style="color: rgba(0, 0, 0, 1)">);
res.write(</span>"网站 URL:" +<span style="color: rgba(0, 0, 0, 1)"> body.url);
} </span><span style="color: rgba(0, 0, 255, 1)">else</span> {<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 输出表单</span>
<span style="color: rgba(0, 0, 0, 1)"> res.write(postHTML);
}
res.end();
});
}).listen(</span>3000);</pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p> </p>
<h1>Node.js 工具模块</h1>
<p>在 Node.js 模块库中有很多好用的模块。接下来我们为大家介绍几种常用模块的使用:</p>
<table class="reference">
<tbody>
<tr><th>序号</th><th>模块名 & 描述</th></tr>
<tr>
<td>1</td>
<td><strong>OS 模块</strong><br>提供基本的系统操作函数。</td>
</tr>
<tr>
<td>2</td>
<td><strong>Path 模块</strong><br>提供了处理和转换文件路径的工具。</td>
</tr>
<tr>
<td>3</td>
<td><strong>Net 模块</strong><br>用于底层的网络通信。提供了服务端和客户端的的操作。</td>
</tr>
<tr>
<td>4</td>
<td><strong>DNS 模块</strong><br>用于解析域名。</td>
</tr>
<tr>
<td>5</td>
<td><strong>Domain 模块</strong><br>简化异步代码的异常处理,可以捕捉处理try catch无法捕捉的。</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<p> </p>
<h1>Node.js Web 模块</h1>
<h2>什么是 Web 服务器?</h2>
<p>Web服务器一般指网站服务器,是指驻留于因特网上某种类型计算机的程序,Web服务器的基本功能就是提供Web信息浏览服务。它只需支持HTTP协议、HTML文档格式及URL,与客户端的网络浏览器配合。</p>
<p>大多数 web 服务器都支持服务端的脚本语言(php、python、ruby)等,并通过脚本语言从数据库获取数据,将结果返回给客户端浏览器。</p>
<p>目前最主流的三个Web服务器是Apache、Nginx、IIS。</p>
<h2>Web 应用架构</h2>
<p><img title="Web 应用架构" src="https://www.runoob.com/wp-content/uploads/2015/09/web_architecture.jpg" alt=""></p>
<ul>
<li>
<p><strong>Client</strong> - 客户端,一般指浏览器,浏览器可以通过 HTTP 协议向服务器请求数据。</p>
</li>
<li>
<p><strong>Server</strong> - 服务端,一般指 Web 服务器,可以接收客户端请求,并向客户端发送响应数据。</p>
</li>
<li>
<p><strong>Business</strong> - 业务层, 通过 Web 服务器处理应用程序,如与数据库交互,逻辑运算,调用外部程序等。</p>
</li>
<li>
<p><strong>Data</strong> - 数据层,一般由数据库组成。</p>
</li>
</ul>
<h2>使用 Node 创建 Web 服务器</h2>
<p>Node.js 提供了 http 模块,http 模块主要用于搭建 HTTP 服务端和客户端,使用 HTTP 服务器或客户端功能必须调用 http 模块,代码如下:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> http = require('http');</pre>
</div>
<p>以下是演示一个最基本的 HTTP 服务器架构(使用 8080 端口),创建 server.js 文件,代码如下所示:</p>
<div class="example">
<h2 class="example">实例</h2>
<div class="cnblogs_code"><img id="code_img_closed_7cc1a463-c293-4747-a5b8-543b47218c5e" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_7cc1a463-c293-4747-a5b8-543b47218c5e" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_7cc1a463-c293-4747-a5b8-543b47218c5e" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> http = require('http'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> fs = require('fs'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> url = require('url'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 创建服务器</span>
http.createServer(<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> (req, res) {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 解析请求</span>
<span style="color: rgba(0, 0, 255, 1)">var</span> pathname =<span style="color: rgba(0, 0, 0, 1)"> url.parse(req.url).pathname;
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 输出请求的文件名</span>
console.log("Request for "+pathname+" received"<span style="color: rgba(0, 0, 0, 1)">);
fs.readFile(pathname.substr(</span>1), <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> (err,data) {
</span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (err){
console.log(err);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> HTTP 状态码:404 :NOT FOUND</span>
<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Content Type:text/html</span>
res.writeHead(404,{'Content-Type':'text/html'<span style="color: rgba(0, 0, 0, 1)">});
}</span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> HTTP 状态码:200 :OK</span>
<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Content Type : text/html</span>
res.writeHead(200,{'Content-Type':'text/html'<span style="color: rgba(0, 0, 0, 1)">});
res.write(data.toString());
}
res.end();
});
}).listen(</span>8080<span style="color: rgba(0, 0, 0, 1)">);
console.log(</span>'Server running at http://127.0.0.1:8080/');</pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
</div>
<p>接下来我们在该目录下创建一个 index.html 文件,代码如下:</p>
<div class="example">
<h2 class="example">index.html 文件</h2>
<div class="cnblogs_code"><img id="code_img_closed_92512f22-73da-412e-86a9-64c8afda4523" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_92512f22-73da-412e-86a9-64c8afda4523" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_92512f22-73da-412e-86a9-64c8afda4523" class="cnblogs_code_hide">
<pre><!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>index page</title>
</head>
<body>
<h1>Index page</h1>
<p><span style="color: rgba(0, 0, 255, 1)">this</span> is p lable</p>
</body>
</html></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
</div>
<p>执行 server.js 文件:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">$ node server.js
Server running at http://127.0.0.1:8080/</span></pre>
</div>
<p>接着我们在浏览器中打开地址:<strong>http://127.0.0.1:8080/index.html</strong>,显示如下图所示:</p>
<p><img src="https://img2018.cnblogs.com/blog/1399348/201910/1399348-20191005170133949-2135257966.png" alt=""></p>
<p>执行 server.js 的控制台输出信息如下:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">Server running at http://127.0.0.1:8080/
Request for /index.html received. #客户端请求信息</span></pre>
</div>
<h2>使用 Node 创建 Web 客户端</h2>
<p>Node 创建 Web 客户端需要引入 http 模块,创建 client.js 文件,代码如下所示:</p>
<div class="example">
<h2 class="example">实例</h2>
<div class="example_code">
<div class="hl-main">
<div class="cnblogs_code"><img id="code_img_closed_f5ee5fd7-6a2b-495f-936b-a98588ac5aa0" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_f5ee5fd7-6a2b-495f-936b-a98588ac5aa0" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_f5ee5fd7-6a2b-495f-936b-a98588ac5aa0" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> http = require('http'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 用于请求的选项</span>
<span style="color: rgba(0, 0, 255, 1)">var</span> options =<span style="color: rgba(0, 0, 0, 1)"> {
host: </span>'localhost'<span style="color: rgba(0, 0, 0, 1)">,
port: </span>'8080'<span style="color: rgba(0, 0, 0, 1)">,
path: </span>'/index.html'<span style="color: rgba(0, 0, 0, 1)">
};
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 处理响应的回调函数</span>
<span style="color: rgba(0, 0, 255, 1)">var</span> callback = <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(response){
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 不断更新数据</span>
<span style="color: rgba(0, 0, 255, 1)">var</span> body = ''<span style="color: rgba(0, 0, 0, 1)">;
response.on(</span>'data', <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(data) {
body </span>+=<span style="color: rgba(0, 0, 0, 1)"> data;
});
response.on(</span>'end', <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">() {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 数据接收完成</span>
<span style="color: rgba(0, 0, 0, 1)"> console.log(body);
});
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 向服务端发送请求</span>
<span style="color: rgba(0, 0, 255, 1)">var</span> req =<span style="color: rgba(0, 0, 0, 1)"> http.request(options, callback);
req.end();</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
</div>
</div>
</div>
<p><strong>新开一个终端</strong>,执行 client.js 文件,输出结果如下:</p>
<div class="cnblogs_code"><img id="code_img_closed_92ea6cdb-c35a-4d95-b14e-ca45ea51ea0b" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_92ea6cdb-c35a-4d95-b14e-ca45ea51ea0b" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_92ea6cdb-c35a-4d95-b14e-ca45ea51ea0b" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 0, 1)">$ nodeclient.js
</span><!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
</head>
<body>
<h1>我的第一个标题</h1>
<p>我的第一个段落。</p>
</body>
</html></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p>执行 server.js 的控制台输出信息如下:</p>
<div class="cnblogs_code">
<pre>Server running at http:<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">127.0.0.1:8080/</span>
Request <span style="color: rgba(0, 0, 255, 1)">for</span> /index.html received. # 客户端请求信息</pre>
</div>
<h1>Node.js Express 框架</h1>
<h2>Express 简介</h2>
<p>Express 是一个简洁而灵活的 <span style="font-size: 14pt"><strong>node.js Web应用框架</strong></span>, 提供了一系列强大特性帮助你创建各种 Web 应用,和丰富的 HTTP 工具。</p>
<p>使用 Express 可以快速地搭建一个完整功能的网站。</p>
<p>Express 框架核心特性:</p>
<ul>
<li>
<p>可以设置中间件来响应 HTTP 请求。</p>
</li>
<li>
<p>定义了路由表用于执行不同的 HTTP 请求动作。</p>
</li>
<li>
<p>可以通过向模板传递参数来动态渲染 HTML 页面。</p>
</li>
</ul>
<h2>安装 Express</h2>
<p>安装 Express 并将其保存到依赖列表中:</p>
<div class="cnblogs_code">
<pre>cnpm install express --save</pre>
</div>
<p> </p>
<p>以上命令会将 Express 框架安装在当前目录的 <strong>node_modules</strong> 目录中, <strong>node_modules</strong> 目录下会自动创建 express 目录。以下几个重要的模块是需要与 express 框架一起安装的:</p>
<ul>
<li>
<p><strong>body-parser</strong> - node.js 中间件,用于处理 JSON, Raw, Text 和 URL 编码的数据。</p>
</li>
<li>
<p><strong>cookie-parser</strong> - 这就是一个解析Cookie的工具。通过req.cookies可以取到传过来的cookie,并把它们转成对象。</p>
</li>
<li>
<p><strong>multer</strong> - node.js 中间件,用于处理 enctype="multipart/form-data"(设置表单的MIME编码)的表单数据。</p>
</li>
</ul>
<div class="cnblogs_code">
<pre>cnpm install body-parser --<span style="color: rgba(0, 0, 0, 1)">save
cnpm install cookie</span>-parser --<span style="color: rgba(0, 0, 0, 1)">save
cnpm install multer </span>--save</pre>
</div>
<p> </p>
<p>安装完后,我们可以查看下 express 使用的版本号:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">cnpm list express
</span>/data/www/node
└── express@4.15.2-> /Users/tianqixin/www/node/node_modules/.4.15.2@express</pre>
</div>
<p> </p>
<h2>第一个 Express 框架实例</h2>
<p>接下来我们使用 Express 框架来输出 "Hello World"。</p>
<p>以下实例中我们引入了 express 模块,并在客户端发起请求后,响应 "Hello World" 字符串。</p>
<p>创建 express_demo.js 文件,代码如下所示:</p>
<div class="example">
<h2 class="example">express_demo.js 文件代码:</h2>
<div class="example_code">
<div class="hl-main">
<div class="cnblogs_code"><img id="code_img_closed_4898c00c-6c38-489c-858b-70970dcc2584" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_4898c00c-6c38-489c-858b-70970dcc2584" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_4898c00c-6c38-489c-858b-70970dcc2584" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">express_demo.js 文件</span>
<span style="color: rgba(0, 0, 255, 1)">var</span> express = require('express'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> app =<span style="color: rgba(0, 0, 0, 1)"> express();
app.get(</span>'/', <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> (req, res) {
res.send(</span>'Hello World'<span style="color: rgba(0, 0, 0, 1)">);
})
</span><span style="color: rgba(0, 0, 255, 1)">var</span> server = app.listen(8081, <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> () {
</span><span style="color: rgba(0, 0, 255, 1)">var</span> host =<span style="color: rgba(0, 0, 0, 1)"> server.address().address
</span><span style="color: rgba(0, 0, 255, 1)">var</span> port =<span style="color: rgba(0, 0, 0, 1)"> server.address().port
console.log(</span>"应用实例,访问地址为 http://%s:%s"<span style="color: rgba(0, 0, 0, 1)">, host, port)
})</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
</div>
</div>
</div>
<p>执行以上代码:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">node express_demo.js
应用实例,访问地址为 http:</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">0.0.0.0:8081</span></pre>
</div>
<p> </p>
<p>在浏览器中访问 http://127.0.0.1:8081,结果如下图所示:</p>
<p><img src="https://img2018.cnblogs.com/blog/1399348/201910/1399348-20191005174340816-1205441428.png" alt=""></p>
<h2>请求和响应</h2>
<p>Express 应用使用回调函数的参数: <strong>request</strong> 和 <strong>response</strong> 对象来处理请求和响应的数据。</p>
<div class="cnblogs_code">
<pre>app.get('/', <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> (req, res) {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> --</span>
})</pre>
</div>
<p> </p>
<p><strong>request</strong> 和 <strong>response</strong> 对象的具体介绍:</p>
<p><strong>Request 对象</strong> - request 对象表示 HTTP 请求,包含了请求查询字符串,参数,内容,HTTP 头部等属性。常见属性有:</p>
<div class="cnblogs_code"><img id="code_img_closed_f24a982d-6fac-428f-8dcf-f70a510d8bea" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_f24a982d-6fac-428f-8dcf-f70a510d8bea" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_f24a982d-6fac-428f-8dcf-f70a510d8bea" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 0, 1)">req.app:当callback为外部文件时,用req.app访问express的实例
req.baseUrl:获取路由当前安装的URL路径
req.body </span>/ req.cookies:获得「请求主体」/<span style="color: rgba(0, 0, 0, 1)"> Cookies
req.fresh </span>/<span style="color: rgba(0, 0, 0, 1)"> req.stale:判断请求是否还「新鲜」
req.hostname </span>/<span style="color: rgba(0, 0, 0, 1)"> req.ip:获取主机名和IP地址
req.originalUrl:获取原始请求URL
req.params:获取路由的parameters
req.path:获取请求路径
req.protocol:获取协议类型
req.query:获取URL的查询参数串
req.route:获取当前匹配的路由
req.subdomains:获取子域名
req.accepts():检查可接受的请求的文档类型
req.acceptsCharsets </span>/ req.acceptsEncodings /<span style="color: rgba(0, 0, 0, 1)"> req.acceptsLanguages:返回指定字符集的第一个可接受字符编码
req.get():获取指定的HTTP请求头
req.is():判断请求头Content</span>-Type的MIME类型</pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p> </p>
<p><strong>Response 对象</strong> - response 对象表示 HTTP 响应,即在接收到请求时向客户端发送的 HTTP 响应数据。常见属性有:</p>
<div class="cnblogs_code"><img id="code_img_closed_b9ab3ac8-a5c4-475d-a8e8-70c8bd061f64" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_b9ab3ac8-a5c4-475d-a8e8-70c8bd061f64" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_b9ab3ac8-a5c4-475d-a8e8-70c8bd061f64" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 0, 1)">res.app:同req.app一样
res.append():追加指定HTTP头
res.set()在res.append()后将重置之前设置的头
res.cookie(name,value [,option]):设置Cookie
opition: domain </span>/ expires / httpOnly / maxAge / path / secure /<span style="color: rgba(0, 0, 0, 1)"> signed
res.clearCookie():清除Cookie
res.download():传送指定路径的文件
res.get():返回指定的HTTP头
res.json():传送JSON响应
res.jsonp():传送JSONP响应
res.location():只设置响应的Location HTTP头,不设置状态码或者close response
res.redirect():设置响应的Location HTTP头,并且设置状态码302
res.render(view,,callback):渲染一个view,同时向callback传递渲染后的字符串,如果在渲染过程中有错误发生next(err)将会被自动调用。callback将会被传入一个可能发生的错误以及渲染后的页面,这样就不会自动输出了。
res.send():传送HTTP响应
res.sendFile(path [,options] [,fn]):传送指定路径的文件 </span>-会自动根据文件extension设定Content-<span style="color: rgba(0, 0, 0, 1)">Type
res.set():设置HTTP头,传入object可以一次设置多个头
res.status():设置HTTP状态码
res.type():设置Content</span>-Type的MIME类型</pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p> </p>
<h2>路由</h2>
<p>我们已经了解了 HTTP 请求的基本应用,而路由决定了由谁(指定脚本)去响应客户端请求。</p>
<p>在HTTP请求中,我们可以通过路由提取出请求的URL以及GET/POST参数。</p>
<p>接下来我们扩展 Hello World,添加一些功能来处理更多类型的 HTTP 请求。</p>
<p>创建 express_demo2.js 文件,代码如下所示:</p>
<div class="example">
<h2 class="example">express_demo2.js 文件代码:</h2>
<div class="example_code">
<div class="hl-main">
<div class="cnblogs_code"><img id="code_img_closed_fe80f1f2-68e9-4886-907e-4d3a4673a743" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_fe80f1f2-68e9-4886-907e-4d3a4673a743" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_fe80f1f2-68e9-4886-907e-4d3a4673a743" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> express = require('express'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> app =<span style="color: rgba(0, 0, 0, 1)"> express();
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">主页输出 "Hello World"</span>
app.get('/', <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> (req, res) {
console.log(</span>"主页 GET 请求"<span style="color: rgba(0, 0, 0, 1)">);
res.send(</span>'Hello GET'<span style="color: rgba(0, 0, 0, 1)">);
})
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">POST 请求</span>
app.post('/', <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> (req, res) {
console.log(</span>"主页 POST 请求"<span style="color: rgba(0, 0, 0, 1)">);
res.send(</span>'Hello POST'<span style="color: rgba(0, 0, 0, 1)">);
})
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">/del_user 页面响应</span>
app.get('/del_user', <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> (req, res) {
console.log(</span>"/del_user 响应 DELETE 请求"<span style="color: rgba(0, 0, 0, 1)">);
res.send(</span>'删除页面'<span style="color: rgba(0, 0, 0, 1)">);
})
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">/list_user 页面 GET 请求</span>
app.get('/list_user', <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> (req, res) {
console.log(</span>"/list_user GET 请求"<span style="color: rgba(0, 0, 0, 1)">);
res.send(</span>'用户列表页面'<span style="color: rgba(0, 0, 0, 1)">);
})
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 对页面 abcd, abxcd, ab123cd, 等响应 GET 请求</span>
app.get('/ab*cd', <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(req, res) {
console.log(</span>"/ab*cd GET 请求"<span style="color: rgba(0, 0, 0, 1)">);
res.send(</span>'正则匹配'<span style="color: rgba(0, 0, 0, 1)">);
})
</span><span style="color: rgba(0, 0, 255, 1)">var</span> server = app.listen(8081, <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> () {
</span><span style="color: rgba(0, 0, 255, 1)">var</span> host =<span style="color: rgba(0, 0, 0, 1)"> server.address().address
</span><span style="color: rgba(0, 0, 255, 1)">var</span> port =<span style="color: rgba(0, 0, 0, 1)"> server.address().port
console.log(</span>"应用实例,访问地址为 http://%s:%s"<span style="color: rgba(0, 0, 0, 1)">, host, port)
})</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p> </p>
</div>
<div class="hl-main">执行以上代码:</div>
</div>
</div>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">node express_demo2.js
应用实例,访问地址为 http:</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">0.0.0.0:8081</span></pre>
</div>
<p> </p>
<p>接下来你可以尝试访问 http://127.0.0.1:8081 不同的地址,查看效果。</p>
<p>在浏览器中访问 http://127.0.0.1:8081/list_user</p>
<p>在浏览器中访问 http://127.0.0.1:8081/abcd</p>
<p>在浏览器中访问 http://127.0.0.1:8081/abcdefg</p>
<h2>静态文件</h2>
<p>Express 提供了内置的中间件<strong> express.static </strong>来设置静态文件如:图片, CSS, JavaScript 等。</p>
<p>你可以使用<strong> express.static </strong>中间件来设置静态文件路径。例如,如果你将图片, CSS, JavaScript 文件放在 public 目录下,你可以这么写:</p>
<div class="cnblogs_code">
<pre>app.use('/public', express.static('public'));</pre>
</div>
<p> </p>
<p>我们可以到 public/images 目录下放些图片,如下所示:</p>
<pre class="prettyprint prettyprinted"><span class="pln">node_modules
server<span class="pun">.<span class="pln">js
<span class="kwd">public<span class="pun">/<span class="pln">
<span class="kwd">public<span class="pun">/<span class="pln">images
<span class="kwd">public<span class="pun">/<span class="pln">images<span class="pun">/<span class="pln">logo<span class="pun">.<span class="pln">png</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></pre>
<p>让我们再修改下 "Hello World" 应用添加处理静态文件的功能。</p>
<p>创建 express_demo3.js 文件,代码如下所示:</p>
<div class="example">
<h2 class="example">express_demo3.js 文件代码:</h2>
<div class="example_code">
<div class="hl-main">
<div class="cnblogs_code"><img id="code_img_closed_1b553ff0-503a-43f4-9a78-297ebbe7cc00" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_1b553ff0-503a-43f4-9a78-297ebbe7cc00" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_1b553ff0-503a-43f4-9a78-297ebbe7cc00" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> express = require('express'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> app =<span style="color: rgba(0, 0, 0, 1)"> express();
app.use(</span>'/public', express.static('public'<span style="color: rgba(0, 0, 0, 1)">));
app.get(</span>'/', <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> (req, res) {
res.send(</span>'Hello World'<span style="color: rgba(0, 0, 0, 1)">);
})
</span><span style="color: rgba(0, 0, 255, 1)">var</span> server = app.listen(8081, <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> () {
</span><span style="color: rgba(0, 0, 255, 1)">var</span> host =<span style="color: rgba(0, 0, 0, 1)"> server.address().address
</span><span style="color: rgba(0, 0, 255, 1)">var</span> port =<span style="color: rgba(0, 0, 0, 1)"> server.address().port
console.log(</span>"应用实例,访问地址为 http://%s:%s"<span style="color: rgba(0, 0, 0, 1)">, host, port)
})</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
</div>
</div>
</div>
<p>执行以上代码:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">node express_demo3.js
应用实例,访问地址为 http:</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">0.0.0.0:8081</span></pre>
</div>
<p> </p>
<p>执行以上代码:</p>
<p>在浏览器中访问 http://127.0.0.1:8081/public/images/logo.png(本实例采用了菜鸟教程的 logo),结果如下图所示:</p>
<p><img src="https://www.runoob.com/wp-content/themes/runoob/assets/img/runoob-logo.png" alt=""></p>
<h2>GET 方法</h2>
<p>以下实例演示了在表单中通过 GET 方法提交两个参数,我们可以使用 server.js 文件内的 <strong>process_get</strong> 路由器来处理输入:</p>
<div class="example">
<h2 class="example">index.htm 文件代码:</h2>
<div class="example_code">
<div class="hl-main">
<div class="cnblogs_code"><img id="code_img_closed_461b84a4-22ea-49c3-95a3-8c3c160b9551" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_461b84a4-22ea-49c3-95a3-8c3c160b9551" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_461b84a4-22ea-49c3-95a3-8c3c160b9551" class="cnblogs_code_hide">
<pre><html>
<body>
<form action="http://127.0.0.1:8081/process_get" method="GET"><span style="color: rgba(0, 0, 0, 1)">
First Name: </span><input type="text" name="first_name"><br><span style="color: rgba(0, 0, 0, 1)">
Last Name: </span><input type="text" name="last_name">
<input type="submit" value="Submit">
</form>
</body>
</html></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p> </p>
</div>
</div>
</div>
<div class="example">
<h2 class="example">server.js 文件代码:</h2>
<div class="example_code">
<div class="hl-main">
<div class="cnblogs_code"><img id="code_img_closed_7384aa52-c85a-4c59-917b-d613dec763cf" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_7384aa52-c85a-4c59-917b-d613dec763cf" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_7384aa52-c85a-4c59-917b-d613dec763cf" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> express = require('express'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> app =<span style="color: rgba(0, 0, 0, 1)"> express();
app.use(</span>'/public', express.static('public'<span style="color: rgba(0, 0, 0, 1)">));
app.get(</span>'/index.htm', <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> (req, res) {
res.sendFile( __dirname </span>+ "/" + "index.htm"<span style="color: rgba(0, 0, 0, 1)"> );
})
app.get(</span>'/process_get', <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> (req, res) {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 输出 JSON 格式</span>
<span style="color: rgba(0, 0, 255, 1)">var</span> response =<span style="color: rgba(0, 0, 0, 1)"> {
</span>"first_name"<span style="color: rgba(0, 0, 0, 1)">:req.query.first_name,
</span>"last_name"<span style="color: rgba(0, 0, 0, 1)">:req.query.last_name
};
console.log(response);
res.end(JSON.stringify(response));
})
</span><span style="color: rgba(0, 0, 255, 1)">var</span> server = app.listen(8081, <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> () {
</span><span style="color: rgba(0, 0, 255, 1)">var</span> host =<span style="color: rgba(0, 0, 0, 1)"> server.address().address
</span><span style="color: rgba(0, 0, 255, 1)">var</span> port =<span style="color: rgba(0, 0, 0, 1)"> server.address().port
console.log(</span>"应用实例,访问地址为 http://%s:%s"<span style="color: rgba(0, 0, 0, 1)">, host, port)
})</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p> </p>
</div>
</div>
</div>
<p>执行以上代码:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">node server.js
应用实例,访问地址为 http:</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">0.0.0.0:8081</span></pre>
</div>
<p> </p>
<p>浏览器访问 http://127.0.0.1:8081/index.htm,如图所示:</p>
<p><img src="https://www.runoob.com/wp-content/uploads/2015/09/express5.jpg" alt=""></p>
<p>现在你可以向表单输入数据,并提交,如下演示:</p>
<p><img src="https://www.runoob.com/wp-content/uploads/2015/09/nodejs-gif6.gif" alt=""></p>
<hr>
<h2>POST 方法</h2>
<p>以下实例演示了在表单中通过 POST 方法提交两个参数,我们可以使用 server.js 文件内的 <strong>process_post</strong> 路由器来处理输入:</p>
<div class="example">
<h2 class="example">index.htm 文件代码:</h2>
<div class="example_code">
<div class="hl-main">
<div class="cnblogs_code"><img id="code_img_closed_6d05b010-545e-4ce2-b8f2-8aca299947af" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_6d05b010-545e-4ce2-b8f2-8aca299947af" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_6d05b010-545e-4ce2-b8f2-8aca299947af" class="cnblogs_code_hide">
<pre><html>
<body>
<form action="http://127.0.0.1:8081/process_post" method="POST"><span style="color: rgba(0, 0, 0, 1)">
First Name: </span><input type="text" name="first_name"><br><span style="color: rgba(0, 0, 0, 1)">
Last Name: </span><input type="text" name="last_name">
<input type="submit" value="Submit">
</form>
</body>
</html></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p> </p>
</div>
</div>
</div>
<div class="example">
<h2 class="example">server.js 文件代码:</h2>
<div class="example_code">
<div class="hl-main">
<div class="cnblogs_code"><img id="code_img_closed_e10472f0-18c5-4fd5-a129-1e221f9cf4d7" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_e10472f0-18c5-4fd5-a129-1e221f9cf4d7" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_e10472f0-18c5-4fd5-a129-1e221f9cf4d7" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> express = require('express'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> app =<span style="color: rgba(0, 0, 0, 1)"> express();
</span><span style="color: rgba(0, 0, 255, 1)">var</span> bodyParser = require('body-parser'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 创建 application/x-www-form-urlencoded 编码解析</span>
<span style="color: rgba(0, 0, 255, 1)">var</span> urlencodedParser = bodyParser.urlencoded({ extended: <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)"> })
app.use(</span>'/public', express.static('public'<span style="color: rgba(0, 0, 0, 1)">));
app.get(</span>'/index.htm', <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> (req, res) {
res.sendFile( __dirname </span>+ "/" + "index.htm"<span style="color: rgba(0, 0, 0, 1)"> );
})
app.post(</span>'/process_post', urlencodedParser, <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> (req, res) {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 输出 JSON 格式</span>
<span style="color: rgba(0, 0, 255, 1)">var</span> response =<span style="color: rgba(0, 0, 0, 1)"> {
</span>"first_name"<span style="color: rgba(0, 0, 0, 1)">:req.body.first_name,
</span>"last_name"<span style="color: rgba(0, 0, 0, 1)">:req.body.last_name
};
console.log(response);
res.end(JSON.stringify(response));
})
</span><span style="color: rgba(0, 0, 255, 1)">var</span> server = app.listen(8081, <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> () {
</span><span style="color: rgba(0, 0, 255, 1)">var</span> host =<span style="color: rgba(0, 0, 0, 1)"> server.address().address
</span><span style="color: rgba(0, 0, 255, 1)">var</span> port =<span style="color: rgba(0, 0, 0, 1)"> server.address().port
console.log(</span>"应用实例,访问地址为 http://%s:%s"<span style="color: rgba(0, 0, 0, 1)">, host, port)
})</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
</div>
</div>
</div>
<p>执行以上代码:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">node server.js
应用实例,访问地址为 http:</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">0.0.0.0:8081</span></pre>
</div>
<p> </p>
<p>浏览器访问 http://127.0.0.1:8081/index.htm,如图所示:</p>
<p><img src="https://www.runoob.com/wp-content/uploads/2015/09/express5.jpg" alt=""></p>
<p>现在你可以向表单输入数据,并提交,如下演示:</p>
<p><img src="https://www.runoob.com/wp-content/uploads/2015/09/nodejs-gif7.gif" alt=""></p>
<hr>
<h2>文件上传</h2>
<p>以下我们创建一个用于上传文件的表单,使用 POST 方法,表单 enctype 属性设置为 multipart/form-data。</p>
<div class="example">
<h2 class="example">index.htm 文件代码:</h2>
<div class="example_code">
<div class="hl-main">
<div class="cnblogs_code"><img id="code_img_closed_d9031952-b08a-4483-9d35-fb7f6bc0932e" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_d9031952-b08a-4483-9d35-fb7f6bc0932e" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_d9031952-b08a-4483-9d35-fb7f6bc0932e" class="cnblogs_code_hide">
<pre><html>
<head>
<title>文件上传表单</title>
</head>
<body>
<h3>文件上传:</h3>
选择一个文件上传: <br />
<form action="/file_upload" method="post" enctype="multipart/form-data">
<input type="file" name="image" size="50" />
<br />
<input type="submit" value="上传文件" />
</form>
</body>
</html></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p> </p>
</div>
</div>
</div>
<div class="example">
<h2 class="example">server.js 文件代码:</h2>
<div class="example_code">
<div class="hl-main">
<div class="cnblogs_code"><img id="code_img_closed_90536d29-f633-49ba-aa81-00829b2feaea" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_90536d29-f633-49ba-aa81-00829b2feaea" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_90536d29-f633-49ba-aa81-00829b2feaea" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> express = require('express'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> app =<span style="color: rgba(0, 0, 0, 1)"> express();
</span><span style="color: rgba(0, 0, 255, 1)">var</span> fs = require("fs"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> bodyParser = require('body-parser'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> multer= require('multer'<span style="color: rgba(0, 0, 0, 1)">);
app.use(</span>'/public', express.static('public'<span style="color: rgba(0, 0, 0, 1)">));
app.use(bodyParser.urlencoded({ extended: </span><span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)"> }));
app.use(multer({ dest: </span>'/tmp/'}).array('image'<span style="color: rgba(0, 0, 0, 1)">));
app.get(</span>'/index.htm', <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> (req, res) {
res.sendFile( __dirname </span>+ "/" + "index.htm"<span style="color: rgba(0, 0, 0, 1)"> );
})
app.post(</span>'/file_upload', <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> (req, res) {
console.log(req.files[</span>0]);<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 上传的文件信息</span>
<span style="color: rgba(0, 0, 255, 1)">var</span> des_file = __dirname + "/" + req.files.originalname;
fs.readFile( req.files[</span>0].path, <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> (err, data) {
fs.writeFile(des_file, data, </span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> (err) {
</span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)">( err ){
console.log( err );
}</span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">{
response </span>=<span style="color: rgba(0, 0, 0, 1)"> {
message:</span>'File uploaded successfully'<span style="color: rgba(0, 0, 0, 1)">,
filename:req.files[</span>0<span style="color: rgba(0, 0, 0, 1)">].originalname
};
}
console.log( response );
res.end( JSON.stringify( response ) );
});
});
})
</span><span style="color: rgba(0, 0, 255, 1)">var</span> server = app.listen(8081, <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> () {
</span><span style="color: rgba(0, 0, 255, 1)">var</span> host =<span style="color: rgba(0, 0, 0, 1)"> server.address().address
</span><span style="color: rgba(0, 0, 255, 1)">var</span> port =<span style="color: rgba(0, 0, 0, 1)"> server.address().port
console.log(</span>"应用实例,访问地址为 http://%s:%s"<span style="color: rgba(0, 0, 0, 1)">, host, port)
})</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p> </p>
</div>
</div>
</div>
<p>执行以上代码:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">node server.js
应用实例,访问地址为 http:</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">0.0.0.0:8081</span></pre>
</div>
<p> </p>
<p>浏览器访问 http://127.0.0.1:8081/index.htm,如图所示:</p>
<p><img src="https://www.runoob.com/wp-content/uploads/2015/09/express6.jpg" alt=""></p>
<p>现在你可以向表单输入数据,并提交,如下演示:</p>
<p><img src="https://www.runoob.com/wp-content/uploads/2015/09/nodejs-gif8.gif" alt=""></p>
<hr>
<h2>Cookie 管理</h2>
<p>我们可以使用中间件向 Node.js 服务器发送 cookie 信息,以下代码输出了客户端发送的 cookie 信息:</p>
<div class="example">
<h2 class="example">express_cookie.js 文件代码:</h2>
<div class="example_code">
<div class="hl-main">
<div class="cnblogs_code"><img id="code_img_closed_e2ffd776-dbbc-4e21-bb00-e5470908371e" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_e2ffd776-dbbc-4e21-bb00-e5470908371e" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_e2ffd776-dbbc-4e21-bb00-e5470908371e" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> express_cookie.js 文件</span>
<span style="color: rgba(0, 0, 255, 1)">var</span> express = require('express'<span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 0, 255, 1)">var</span> cookieParser = require('cookie-parser'<span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 0, 255, 1)">var</span> util = require('util'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> app =<span style="color: rgba(0, 0, 0, 1)"> express()
app.use(cookieParser())
app.get(</span>'/', <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(req, res) {
console.log(</span>"Cookies: " +<span style="color: rgba(0, 0, 0, 1)"> util.inspect(req.cookies));
})
app.listen(</span>8081)</pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p> </p>
</div>
</div>
</div>
<p>执行以上代码:</p>
<div class="cnblogs_code">
<pre>node express_cookie.js </pre>
</div>
<p> </p>
<p>现在你可以访问 http://127.0.0.1:8081 并查看终端信息的输出,如下演示:</p>
<p><img src="https://www.runoob.com/wp-content/uploads/2015/09/nodejs-gif9.gif" alt=""></p>
<hr>
<h2>相关资料</h2>
<ul>
<li>Express官网: http://expressjs.com/</li>
<li>Express4.x API 中文版: Express4.x API Chinese</li>
<li>Express4.x API:http://expressjs.com/zh-cn/4x/api.html</li>
</ul>
<h1>Node.js RESTful API</h1>
<h2>什么是 REST?</h2>
<p>REST即表述性状态传递(英文:Representational State Transfer,简称REST)是Roy Fielding博士在2000年他的博士论文中提出来的一种软件架构风格。</p>
<p>表述性状态转移是一组架构约束条件和原则。满足这些约束条件和原则的应用程序或设计就是RESTful。需要注意的是,REST是设计风格而不是标准。REST通常基于使用HTTP,URI,和XML(标准通用标记语言下的一个子集)以及HTML(标准通用标记语言下的一个应用)这些现有的广泛流行的协议和标准。REST 通常使用 JSON 数据格式。</p>
<h3>HTTP 方法</h3>
<p>以下为 REST 基本架构的四个方法:</p>
<p> </p>
<ul>
<li>
<p><strong>GET</strong> - 用于获取数据。</p>
</li>
<li>
<p><strong>PUT</strong> - 用于更新或添加数据。</p>
</li>
<li>
<p><strong>DELETE</strong> - 用于删除数据。</p>
</li>
<li>
<p><strong>POST</strong> - 用于添加数据。</p>
</li>
</ul>
<h2>RESTful Web Services</h2>
<p>Web service是一个平台独立的,低耦合的,自包含的、基于可编程的web的应用程序,可使用开放的XML(标准通用标记语言下的一个子集)标准来描述、发布、发现、协调和配置这些应用程序,用于开发分布式的互操作的应用程序。</p>
<p>基于 REST 架构的 Web Services 即是 RESTful。</p>
<p>由于轻量级以及通过 HTTP 直接传输数据的特性,Web 服务的 RESTful 方法已经成为最常见的替代方法。可以使用各种语言(比如 Java 程序、Perl、Ruby、Python、PHP 和 Javascript[包括 Ajax])实现客户端。</p>
<p>RESTful Web 服务通常可以通过自动客户端或代表用户的应用程序访问。但是,这种服务的简便性让用户能够与之直接交互,使用它们的 Web 浏览器构建一个 GET URL 并读取返回的内容。</p>
<p>更多介绍,可以查看:RESTful 架构详解</p>
<h2>创建 RESTful</h2>
<p>首先,创建一个 json 数据资源文件 users.json,内容如下:</p>
<div class="cnblogs_code"><img id="code_img_closed_cc149a7c-19ee-4df7-a974-de8b56f126fe" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_cc149a7c-19ee-4df7-a974-de8b56f126fe" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_cc149a7c-19ee-4df7-a974-de8b56f126fe" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 0, 1)">{
</span>"user1"<span style="color: rgba(0, 0, 0, 1)"> : {
</span>"name" : "mahesh"<span style="color: rgba(0, 0, 0, 1)">,
</span>"password" : "password1"<span style="color: rgba(0, 0, 0, 1)">,
</span>"profession" : "teacher"<span style="color: rgba(0, 0, 0, 1)">,
</span>"id": 1<span style="color: rgba(0, 0, 0, 1)">
},
</span>"user2"<span style="color: rgba(0, 0, 0, 1)"> : {
</span>"name" : "suresh"<span style="color: rgba(0, 0, 0, 1)">,
</span>"password" : "password2"<span style="color: rgba(0, 0, 0, 1)">,
</span>"profession" : "librarian"<span style="color: rgba(0, 0, 0, 1)">,
</span>"id": 2<span style="color: rgba(0, 0, 0, 1)">
},
</span>"user3"<span style="color: rgba(0, 0, 0, 1)"> : {
</span>"name" : "ramesh"<span style="color: rgba(0, 0, 0, 1)">,
</span>"password" : "password3"<span style="color: rgba(0, 0, 0, 1)">,
</span>"profession" : "clerk"<span style="color: rgba(0, 0, 0, 1)">,
</span>"id": 3<span style="color: rgba(0, 0, 0, 1)">
}
}</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p> </p>
<p>基于以上数据,我们创建以下 RESTful API:</p>
<table class="reference">
<tbody>
<tr><th>序号</th><th>URI</th><th>HTTP 方法</th><th>发送内容</th><th>结果</th></tr>
<tr>
<td>1</td>
<td>listUsers</td>
<td>GET</td>
<td>空</td>
<td>显示所有用户列表</td>
</tr>
<tr>
<td>2</td>
<td>addUser</td>
<td>POST</td>
<td>JSON 字符串</td>
<td>添加新用户</td>
</tr>
<tr>
<td>3</td>
<td>deleteUser</td>
<td>DELETE</td>
<td>JSON 字符串</td>
<td>删除用户</td>
</tr>
<tr>
<td>4</td>
<td>:id</td>
<td>GET</td>
<td>空</td>
<td>显示用户详细信息</td>
</tr>
</tbody>
</table>
<h3>获取用户列表:</h3>
<p>以下代码,我们创建了 RESTful API <strong>listUsers</strong>,用于读取用户的信息列表, server.js 文件代码如下所示:</p>
<div class="cnblogs_code"><img id="code_img_closed_9e26434a-1bf6-4dbf-8d53-cc4bd760421f" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_9e26434a-1bf6-4dbf-8d53-cc4bd760421f" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_9e26434a-1bf6-4dbf-8d53-cc4bd760421f" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> express = require('express'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> app =<span style="color: rgba(0, 0, 0, 1)"> express();
</span><span style="color: rgba(0, 0, 255, 1)">var</span> fs = require("fs"<span style="color: rgba(0, 0, 0, 1)">);
app.get(</span>'/listUsers', <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> (req, res) {
fs.readFile( __dirname </span>+ "/" + "users.json", 'utf8', <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> (err, data) {
console.log( data );
res.end( data );
});
})
</span><span style="color: rgba(0, 0, 255, 1)">var</span> server = app.listen(8081, <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> () {
</span><span style="color: rgba(0, 0, 255, 1)">var</span> host =<span style="color: rgba(0, 0, 0, 1)"> server.address().address
</span><span style="color: rgba(0, 0, 255, 1)">var</span> port =<span style="color: rgba(0, 0, 0, 1)"> server.address().port
console.log(</span>"应用实例,访问地址为 http://%s:%s"<span style="color: rgba(0, 0, 0, 1)">, host, port)
})</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p> </p>
<p>接下来执行以下命令:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">node server.js
应用实例,访问地址为 http:</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">0.0.0.0:8081</span></pre>
</div>
<p> </p>
<p>在浏览器中访问 http://127.0.0.1:8081/listUsers,结果如下所示:</p>
<div class="cnblogs_code"><img id="code_img_closed_2403c302-ac98-4eed-8464-a3b891615cf4" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_2403c302-ac98-4eed-8464-a3b891615cf4" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_2403c302-ac98-4eed-8464-a3b891615cf4" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 0, 1)">{
</span>"user1"<span style="color: rgba(0, 0, 0, 1)"> : {
</span>"name" : "mahesh"<span style="color: rgba(0, 0, 0, 1)">,
</span>"password" : "password1"<span style="color: rgba(0, 0, 0, 1)">,
</span>"profession" : "teacher"<span style="color: rgba(0, 0, 0, 1)">,
</span>"id": 1<span style="color: rgba(0, 0, 0, 1)">
},
</span>"user2"<span style="color: rgba(0, 0, 0, 1)"> : {
</span>"name" : "suresh"<span style="color: rgba(0, 0, 0, 1)">,
</span>"password" : "password2"<span style="color: rgba(0, 0, 0, 1)">,
</span>"profession" : "librarian"<span style="color: rgba(0, 0, 0, 1)">,
</span>"id": 2<span style="color: rgba(0, 0, 0, 1)">
},
</span>"user3"<span style="color: rgba(0, 0, 0, 1)"> : {
</span>"name" : "ramesh"<span style="color: rgba(0, 0, 0, 1)">,
</span>"password" : "password3"<span style="color: rgba(0, 0, 0, 1)">,
</span>"profession" : "clerk"<span style="color: rgba(0, 0, 0, 1)">,
</span>"id": 3<span style="color: rgba(0, 0, 0, 1)">
}
}</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p> </p>
<h3>添加用户</h3>
<p>以下代码,我们创建了 RESTful API <strong>addUser</strong>, 用于添加新的用户数据,server.js 文件代码如下所示:</p>
<div class="cnblogs_code"><img id="code_img_closed_08fb202f-bd50-4b5e-8000-9ef11125b6c5" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_08fb202f-bd50-4b5e-8000-9ef11125b6c5" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_08fb202f-bd50-4b5e-8000-9ef11125b6c5" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> express = require('express'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> app =<span style="color: rgba(0, 0, 0, 1)"> express();
</span><span style="color: rgba(0, 0, 255, 1)">var</span> fs = require("fs"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">添加的新用户数据</span>
<span style="color: rgba(0, 0, 255, 1)">var</span> user =<span style="color: rgba(0, 0, 0, 1)"> {
</span>"user4"<span style="color: rgba(0, 0, 0, 1)"> : {
</span>"name" : "mohit"<span style="color: rgba(0, 0, 0, 1)">,
</span>"password" : "password4"<span style="color: rgba(0, 0, 0, 1)">,
</span>"profession" : "teacher"<span style="color: rgba(0, 0, 0, 1)">,
</span>"id": 4<span style="color: rgba(0, 0, 0, 1)">
}
}
app.get(</span>'/addUser', <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> (req, res) {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 读取已存在的数据</span>
fs.readFile( __dirname + "/" + "users.json", 'utf8', <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> (err, data) {
data </span>=<span style="color: rgba(0, 0, 0, 1)"> JSON.parse( data );
data[</span>"user4"] = user["user4"<span style="color: rgba(0, 0, 0, 1)">];
console.log( data );
res.end( JSON.stringify(data));
});
})
</span><span style="color: rgba(0, 0, 255, 1)">var</span> server = app.listen(8081, <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> () {
</span><span style="color: rgba(0, 0, 255, 1)">var</span> host =<span style="color: rgba(0, 0, 0, 1)"> server.address().address
</span><span style="color: rgba(0, 0, 255, 1)">var</span> port =<span style="color: rgba(0, 0, 0, 1)"> server.address().port
console.log(</span>"应用实例,访问地址为 http://%s:%s"<span style="color: rgba(0, 0, 0, 1)">, host, port)
})</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p> </p>
<p>接下来执行以下命令:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">node server.js
应用实例,访问地址为 http:</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">0.0.0.0:8081</span></pre>
</div>
<p> </p>
<p>在浏览器中访问 http://127.0.0.1:8081/addUser,结果如下所示:</p>
<div class="cnblogs_code"><img id="code_img_closed_b6e31bf5-3202-46e5-94f6-e362289210c0" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_b6e31bf5-3202-46e5-94f6-e362289210c0" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_b6e31bf5-3202-46e5-94f6-e362289210c0" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 0, 1)">{ user1:
{ name: </span>'mahesh'<span style="color: rgba(0, 0, 0, 1)">,
password: </span>'password1'<span style="color: rgba(0, 0, 0, 1)">,
profession: </span>'teacher'<span style="color: rgba(0, 0, 0, 1)">,
id: </span>1<span style="color: rgba(0, 0, 0, 1)"> },
user2:
{ name: </span>'suresh'<span style="color: rgba(0, 0, 0, 1)">,
password: </span>'password2'<span style="color: rgba(0, 0, 0, 1)">,
profession: </span>'librarian'<span style="color: rgba(0, 0, 0, 1)">,
id: </span>2<span style="color: rgba(0, 0, 0, 1)"> },
user3:
{ name: </span>'ramesh'<span style="color: rgba(0, 0, 0, 1)">,
password: </span>'password3'<span style="color: rgba(0, 0, 0, 1)">,
profession: </span>'clerk'<span style="color: rgba(0, 0, 0, 1)">,
id: </span>3<span style="color: rgba(0, 0, 0, 1)"> },
user4:
{ name: </span>'mohit'<span style="color: rgba(0, 0, 0, 1)">,
password: </span>'password4'<span style="color: rgba(0, 0, 0, 1)">,
profession: </span>'teacher'<span style="color: rgba(0, 0, 0, 1)">,
id: </span>4<span style="color: rgba(0, 0, 0, 1)"> }
}</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p> </p>
<h3>显示用户详情</h3>
<p>以下代码,我们创建了 RESTful API <strong>:id(用户id)</strong>, 用于读取指定用户的详细信息,server.js 文件代码如下所示:</p>
<div class="cnblogs_code"><img id="code_img_closed_c69d346a-72e0-47d3-bd7a-16d36c0cc0e0" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_c69d346a-72e0-47d3-bd7a-16d36c0cc0e0" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_c69d346a-72e0-47d3-bd7a-16d36c0cc0e0" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> express = require('express'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> app =<span style="color: rgba(0, 0, 0, 1)"> express();
</span><span style="color: rgba(0, 0, 255, 1)">var</span> fs = require("fs"<span style="color: rgba(0, 0, 0, 1)">);
app.get(</span>'/:id', <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> (req, res) {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 首先我们读取已存在的用户</span>
fs.readFile( __dirname + "/" + "users.json", 'utf8', <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> (err, data) {
data </span>=<span style="color: rgba(0, 0, 0, 1)"> JSON.parse( data );
</span><span style="color: rgba(0, 0, 255, 1)">var</span> user = data["user" +<span style="color: rgba(0, 0, 0, 1)"> req.params.id]
console.log( user );
res.end( JSON.stringify(user));
});
})
</span><span style="color: rgba(0, 0, 255, 1)">var</span> server = app.listen(8081, <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> () {
</span><span style="color: rgba(0, 0, 255, 1)">var</span> host =<span style="color: rgba(0, 0, 0, 1)"> server.address().address
</span><span style="color: rgba(0, 0, 255, 1)">var</span> port =<span style="color: rgba(0, 0, 0, 1)"> server.address().port
console.log(</span>"应用实例,访问地址为 http://%s:%s"<span style="color: rgba(0, 0, 0, 1)">, host, port)
})</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p> </p>
<p>接下来执行以下命令:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">node server.js
应用实例,访问地址为 http:</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">0.0.0.0:8081</span></pre>
</div>
<p> </p>
<p>在浏览器中访问 http://127.0.0.1:8081/2,结果如下所示:</p>
<div class="cnblogs_code"><img id="code_img_closed_453c4531-687e-472d-9c50-e6dd54779f2f" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_453c4531-687e-472d-9c50-e6dd54779f2f" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_453c4531-687e-472d-9c50-e6dd54779f2f" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 0, 1)">{
</span>"name":"suresh"<span style="color: rgba(0, 0, 0, 1)">,
</span>"password":"password2"<span style="color: rgba(0, 0, 0, 1)">,
</span>"profession":"librarian"<span style="color: rgba(0, 0, 0, 1)">,
</span>"id":2<span style="color: rgba(0, 0, 0, 1)">
}</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p> </p>
<h3>删除用户</h3>
<p>以下代码,我们创建了 RESTful API <strong>deleteUser</strong>, 用于删除指定用户的详细信息,以下实例中,用户 id 为 2,server.js 文件代码如下所示:</p>
<div class="cnblogs_code"><img id="code_img_closed_c264e8a7-f590-40ac-b8b3-6dac478b3007" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_c264e8a7-f590-40ac-b8b3-6dac478b3007" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_c264e8a7-f590-40ac-b8b3-6dac478b3007" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> express = require('express'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> app =<span style="color: rgba(0, 0, 0, 1)"> express();
</span><span style="color: rgba(0, 0, 255, 1)">var</span> fs = require("fs"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> id = 2<span style="color: rgba(0, 0, 0, 1)">;
app.get(</span>'/deleteUser', <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> (req, res) {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> First read existing users.</span>
fs.readFile( __dirname + "/" + "users.json", 'utf8', <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> (err, data) {
data </span>=<span style="color: rgba(0, 0, 0, 1)"> JSON.parse( data );
</span><span style="color: rgba(0, 0, 255, 1)">delete</span> data["user" +<span style="color: rgba(0, 0, 0, 1)"> id];
console.log( data );
res.end( JSON.stringify(data));
});
})
</span><span style="color: rgba(0, 0, 255, 1)">var</span> server = app.listen(8081, <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> () {
</span><span style="color: rgba(0, 0, 255, 1)">var</span> host =<span style="color: rgba(0, 0, 0, 1)"> server.address().address
</span><span style="color: rgba(0, 0, 255, 1)">var</span> port =<span style="color: rgba(0, 0, 0, 1)"> server.address().port
console.log(</span>"应用实例,访问地址为 http://%s:%s"<span style="color: rgba(0, 0, 0, 1)">, host, port)
})</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p> </p>
<p>接下来执行以下命令:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">node server.js
应用实例,访问地址为 http:</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">0.0.0.0:8081</span></pre>
</div>
<p>在浏览器中访问 http://127.0.0.1:8081/deleteUser,结果如下所示:</p>
<div class="cnblogs_code"><img id="code_img_closed_1ea3b2e2-3c12-4eba-9cab-c46275478d49" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_1ea3b2e2-3c12-4eba-9cab-c46275478d49" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_1ea3b2e2-3c12-4eba-9cab-c46275478d49" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 0, 1)">{ user1:
{ name: </span>'mahesh'<span style="color: rgba(0, 0, 0, 1)">,
password: </span>'password1'<span style="color: rgba(0, 0, 0, 1)">,
profession: </span>'teacher'<span style="color: rgba(0, 0, 0, 1)">,
id: </span>1<span style="color: rgba(0, 0, 0, 1)"> },
user3:
{ name: </span>'ramesh'<span style="color: rgba(0, 0, 0, 1)">,
password: </span>'password3'<span style="color: rgba(0, 0, 0, 1)">,
profession: </span>'clerk'<span style="color: rgba(0, 0, 0, 1)">,
id: </span>3<span style="color: rgba(0, 0, 0, 1)"> }
}</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p> </p>
<h1>Node.js 多进程</h1>
<p>我们都知道 Node.js 是以单线程的模式运行的,但它使用的是事件驱动来处理并发,这样有助于我们在多核 cpu 的系统上创建多个子进程,从而提高性能。</p>
<p>每个子进程总是带有三个流对象:</p>
<p><strong><span style="font-size: 18pt">child.stdin</span></strong></p>
<p><strong><span style="font-size: 18pt">child.stdout </span></strong></p>
<p><strong><span style="font-size: 18pt">child.stderr</span></strong></p>
<p>他们可能会共享父进程的 stdio 流,或者也可以是独立的被导流的流对象。</p>
<p>Node 提供了 child_process 模块来创建子进程,方法有:</p>
<ul>
<li>
<p><strong>exec</strong> - child_process.exec 使用子进程执行命令,缓存子进程的输出,并将子进程的输出以回调函数参数的形式返回。</p>
</li>
<li>
<p><strong>spawn</strong> - child_process.spawn 使用指定的命令行参数创建新进程。</p>
</li>
<li>
<p><strong>fork</strong> - child_process.fork 是 spawn()的特殊形式,用于在子进程中运行的模块,如 fork('./son.js') 相当于 spawn('node', ['./son.js']) 。与spawn方法不同的是,fork会在父进程与子进程之间,建立一个通信管道,用于进程之间的通信。</p>
</li>
</ul>
<h2>exec() 方法</h2>
<p>child_process.exec 使用子进程执行命令,缓存子进程的输出,并将子进程的输出以回调函数参数的形式返回。</p>
<p>语法如下所示:</p>
<div class="cnblogs_code">
<pre>child_process.exec(command[, options], callback)</pre>
</div>
<p> </p>
<h3>参数</h3>
<p>参数说明如下:</p>
<p><strong>command:</strong> 字符串, 将要运行的命令,参数使用空格隔开</p>
<p><strong>options :对象,可以是:</strong></p>
<ul>
<li>cwd ,字符串,子进程的当前工作目录</li>
<li>env,对象 环境变量键值对</li>
<li>encoding ,字符串,字符编码(默认: 'utf8')</li>
<li>shell ,字符串,将要执行命令的 Shell(默认: 在 UNIX 中为<code>/bin/sh</code>, 在 Windows 中为<code>cmd.exe</code>, Shell 应当能识别 <code>-c</code>开关在 UNIX 中,或 <code>/s /c</code> 在 Windows 中。 在Windows 中,命令行解析应当能兼容<code>cmd.exe</code>)</li>
<li>timeout,数字,超时时间(默认: 0)</li>
<li>maxBuffer,数字, 在 stdout 或 stderr 中允许存在的最大缓冲(二进制),如果超出那么子进程将会被杀死 (默认: 200*1024)</li>
<li>killSignal ,字符串,结束信号(默认:'SIGTERM')</li>
<li>uid,数字,设置用户进程的 ID</li>
<li>gid,数字,设置进程组的 ID</li>
</ul>
<p><strong>callback :</strong>回调函数,包含三个参数error, stdout 和 stderr。</p>
<p>exec() 方法返回最大的缓冲区,并等待进程结束,一次性返回缓冲区的内容。</p>
<h3>实例</h3>
<p>让我们创建两个 js 文件 support.js 和 master.js。</p>
<div class="example">
<h2 class="example_head">support.js 文件代码:</h2>
<div class="example_result">
<div class="hl-main">
<div class="cnblogs_code">
<pre>console.log("进程 " + process.argv + " 执行。" );</pre>
</div>
</div>
</div>
</div>
<div class="example">
<h2 class="example_head">master.js 文件代码:</h2>
<div class="example_result">
<div class="hl-main"><span class="hl-reserved">const<span class="hl-code"> <span class="hl-identifier">fs<span class="hl-code"> = <span class="hl-identifier">require<span class="hl-brackets">(<span class="hl-quotes">'<span class="hl-string">fs<span class="hl-quotes">'<span class="hl-brackets">)<span class="hl-code">; <span class="hl-reserved">const<span class="hl-code"> <span class="hl-identifier">child_process<span class="hl-code"> = <span class="hl-identifier">require<span class="hl-brackets">(<span class="hl-quotes">'<span class="hl-string">child_process<span class="hl-quotes">'<span class="hl-brackets">)<span class="hl-code">; <span class="hl-reserved">for<span class="hl-brackets">(<span class="hl-reserved">var<span class="hl-code"> <span class="hl-identifier">i<span class="hl-code">=<span class="hl-number">0<span class="hl-code">; <span class="hl-identifier">i<span class="hl-code"><<span class="hl-number">3<span class="hl-code">; <span class="hl-identifier">i<span class="hl-code">++<span class="hl-brackets">)<span class="hl-code"> <span class="hl-brackets">{<span class="hl-code"> <span class="hl-reserved">var<span class="hl-code"> <span class="hl-identifier">workerProcess<span class="hl-code"> = <span class="hl-identifier">child_process<span class="hl-code">.<span class="hl-identifier">exec<span class="hl-brackets">(<span class="hl-quotes">'<span class="hl-string">node support.js <span class="hl-quotes">'<span class="hl-code">+<span class="hl-identifier">i<span class="hl-code">, <span class="hl-reserved">function<span class="hl-code"> <span class="hl-brackets">(<span class="hl-identifier">error<span class="hl-code">, <span class="hl-identifier">stdout<span class="hl-code">, <span class="hl-identifier">stderr<span class="hl-brackets">)<span class="hl-code"> <span class="hl-brackets">{<span class="hl-code"> <span class="hl-reserved">if<span class="hl-code"> <span class="hl-brackets">(<span class="hl-identifier">error<span class="hl-brackets">)<span class="hl-code"> <span class="hl-brackets">{<span class="hl-code"> <span class="hl-identifier">console<span class="hl-code">.<span class="hl-identifier">log<span class="hl-brackets">(<span class="hl-identifier">error<span class="hl-code">.<span class="hl-identifier">stack<span class="hl-brackets">)<span class="hl-code">; <span class="hl-identifier">console<span class="hl-code">.<span class="hl-identifier">log<span class="hl-brackets">(<span class="hl-quotes">'<span class="hl-string">Error code: <span class="hl-quotes">'<span class="hl-code">+<span class="hl-identifier">error<span class="hl-code">.<span class="hl-identifier">code<span class="hl-brackets">)<span class="hl-code">; <span class="hl-identifier">console<span class="hl-code">.<span class="hl-identifier">log<span class="hl-brackets">(<span class="hl-quotes">'<span class="hl-string">Signal received: <span class="hl-quotes">'<span class="hl-code">+<span class="hl-identifier">error<span class="hl-code">.<span class="hl-identifier">signal<span class="hl-brackets">)<span class="hl-code">; <span class="hl-brackets">}<span class="hl-code"> <span class="hl-identifier">console<span class="hl-code">.<span class="hl-identifier">log<span class="hl-brackets">(<span class="hl-quotes">'<span class="hl-string">stdout: <span class="hl-quotes">'<span class="hl-code"> + <span class="hl-identifier">stdout<span class="hl-brackets">)<span class="hl-code">; <span class="hl-identifier">console<span class="hl-code">.<span class="hl-identifier">log<span class="hl-brackets">(<span class="hl-quotes">'<span class="hl-string">stderr: <span class="hl-quotes">'<span class="hl-code"> + <span class="hl-identifier">stderr<span class="hl-brackets">)<span class="hl-code">; <span class="hl-brackets">}<span class="hl-brackets">)<span class="hl-code">; <span class="hl-identifier">workerProcess<span class="hl-code">.<span class="hl-identifier">on<span class="hl-brackets">(<span class="hl-quotes">'<span class="hl-string">exit<span class="hl-quotes">'<span class="hl-code">, <span class="hl-reserved">function<span class="hl-code"> <span class="hl-brackets">(<span class="hl-identifier">code<span class="hl-brackets">)<span class="hl-code"> <span class="hl-brackets">{<span class="hl-code"> <span class="hl-identifier">console<span class="hl-code">.<span class="hl-identifier">log<span class="hl-brackets">(<span class="hl-quotes">'<span class="hl-string">子进程已退出,退出码 <span class="hl-quotes">'<span class="hl-code">+<span class="hl-identifier">code<span class="hl-brackets">)<span class="hl-code">; <span class="hl-brackets">}<span class="hl-brackets">)<span class="hl-code">; <span class="hl-brackets">}</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></div>
</div>
</div>
<p>执行以上代码,输出结果为:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">node master.js
子进程已退出,退出码 </span>0<span style="color: rgba(0, 0, 0, 1)">
stdout: 进程 </span>1<span style="color: rgba(0, 0, 0, 1)"> 执行。
stderr:
子进程已退出,退出码 </span>0<span style="color: rgba(0, 0, 0, 1)">
stdout: 进程 </span>0<span style="color: rgba(0, 0, 0, 1)"> 执行。
stderr:
子进程已退出,退出码 </span>0<span style="color: rgba(0, 0, 0, 1)">
stdout: 进程 </span>2<span style="color: rgba(0, 0, 0, 1)"> 执行。
stderr:</span></pre>
</div>
<p> </p>
<h2>spawn() 方法</h2>
<p>child_process.spawn 使用指定的命令行参数创建新进程,语法格式如下:</p>
<div class="cnblogs_code">
<pre>child_process.spawn(command[, args][, options])</pre>
</div>
<p> </p>
<h3>参数</h3>
<p>参数说明如下:</p>
<p><strong>command:</strong> 将要运行的命令</p>
<p><strong>args:</strong> Array 字符串参数数组</p>
<p><strong>options Object</strong></p>
<ul>
<li>cwd String 子进程的当前工作目录</li>
<li>env Object 环境变量键值对</li>
<li>stdio Array|String 子进程的 stdio 配置</li>
<li>detached Boolean 这个子进程将会变成进程组的领导</li>
<li>uid Number 设置用户进程的 ID</li>
<li>gid Number 设置进程组的 ID</li>
</ul>
<p>spawn() 方法返回流 (stdout & stderr),在进程返回大量数据时使用。进程一旦开始执行时 spawn() 就开始接收响应。</p>
<h3>实例</h3>
<p>让我们创建两个 js 文件 support.js 和 master.js。</p>
<div class="example">
<h2 class="example_head">support.js 文件代码:</h2>
<div class="example_result">
<div class="hl-main">
<div class="cnblogs_code">
<pre>console.log("进程 " + process.argv + " 执行。" );</pre>
</div>
</div>
</div>
</div>
<div class="example">
<h2 class="example_head">master.js 文件代码:</h2>
<div class="example_result">
<div class="hl-main">
<div class="cnblogs_code"><img id="code_img_closed_642b9ecd-6bc2-4bb8-832e-acd80e0a5dc1" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_642b9ecd-6bc2-4bb8-832e-acd80e0a5dc1" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_642b9ecd-6bc2-4bb8-832e-acd80e0a5dc1" class="cnblogs_code_hide">
<pre>const fs = require('fs'<span style="color: rgba(0, 0, 0, 1)">);
const child_process </span>= require('child_process'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">for</span>(<span style="color: rgba(0, 0, 255, 1)">var</span> i=0; i<3; i++<span style="color: rgba(0, 0, 0, 1)">) {
</span><span style="color: rgba(0, 0, 255, 1)">var</span> workerProcess = child_process.spawn('node', ['support.js'<span style="color: rgba(0, 0, 0, 1)">, i]);
workerProcess.stdout.on(</span>'data', <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> (data) {
console.log(</span>'stdout: ' +<span style="color: rgba(0, 0, 0, 1)"> data);
});
workerProcess.stderr.on(</span>'data', <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> (data) {
console.log(</span>'stderr: ' +<span style="color: rgba(0, 0, 0, 1)"> data);
});
workerProcess.on(</span>'close', <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> (code) {
console.log(</span>'子进程已退出,退出码 '+<span style="color: rgba(0, 0, 0, 1)">code);
});
}</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p> </p>
</div>
</div>
</div>
<p>执行以上代码,输出结果为:</p>
<div class="cnblogs_code">
<pre>node master.js stdout: 进程 0<span style="color: rgba(0, 0, 0, 1)"> 执行。
子进程已退出,退出码 </span>0<span style="color: rgba(0, 0, 0, 1)">
stdout: 进程 </span>1<span style="color: rgba(0, 0, 0, 1)"> 执行。
子进程已退出,退出码 </span>0<span style="color: rgba(0, 0, 0, 1)">
stdout: 进程 </span>2<span style="color: rgba(0, 0, 0, 1)"> 执行。
子进程已退出,退出码 </span>0</pre>
</div>
<p> </p>
<h2>fork 方法</h2>
<p>child_process.fork 是 spawn() 方法的特殊形式,用于创建进程,语法格式如下:</p>
<div class="cnblogs_code">
<pre>child_process.fork(modulePath[, args][, options])</pre>
</div>
<p> </p>
<h3>参数</h3>
<p>参数说明如下:</p>
<p><strong>modulePath</strong>: String,将要在子进程中运行的模块</p>
<p><strong>args</strong>: Array 字符串参数数组</p>
<p><strong>options</strong>:Object</p>
<ul>
<li>cwd String 子进程的当前工作目录</li>
<li>env Object 环境变量键值对</li>
<li>execPath String 创建子进程的可执行文件</li>
<li>execArgv Array 子进程的可执行文件的字符串参数数组(默认: process.execArgv)</li>
<li>silent Boolean 如果为<code>true</code>,子进程的<code>stdin</code>,<code>stdout</code>和<code>stderr</code>将会被关联至父进程,否则,它们将会从父进程中继承。(默认为:<code>false</code>)</li>
<li>uid Number 设置用户进程的 ID</li>
<li>gid Number 设置进程组的 ID</li>
</ul>
<p>返回的对象除了拥有ChildProcess实例的所有方法,还有一个内建的通信信道。</p>
<h3>实例</h3>
<p>让我们创建两个 js 文件 support.js 和 master.js。</p>
<div class="example">
<h2 class="example_head">support.js 文件代码:</h2>
<div class="example_result">
<div class="hl-main">
<div class="cnblogs_code">
<pre>console.log("进程 " + process.argv + " 执行。" );</pre>
</div>
</div>
</div>
</div>
<div class="example">
<h2 class="example_head">master.js 文件代码:</h2>
<div class="example_result">
<div class="hl-main">
<div class="cnblogs_code"><img id="code_img_closed_07b23145-94d5-4260-a476-9f60bce6f1df" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_07b23145-94d5-4260-a476-9f60bce6f1df" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_07b23145-94d5-4260-a476-9f60bce6f1df" class="cnblogs_code_hide">
<pre>const fs = require('fs'<span style="color: rgba(0, 0, 0, 1)">);
const child_process </span>= require('child_process'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">for</span>(<span style="color: rgba(0, 0, 255, 1)">var</span> i=0; i<3; i++<span style="color: rgba(0, 0, 0, 1)">) {
</span><span style="color: rgba(0, 0, 255, 1)">var</span> worker_process = child_process.fork("support.js"<span style="color: rgba(0, 0, 0, 1)">, );
worker_process.on(</span>'close', <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> (code) {
console.log(</span>'子进程已退出,退出码 ' +<span style="color: rgba(0, 0, 0, 1)"> code);
});
}</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p> </p>
</div>
</div>
</div>
<p>执行以上代码,输出结果为:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">node master.js
进程 </span>0<span style="color: rgba(0, 0, 0, 1)"> 执行。
子进程已退出,退出码 </span>0<span style="color: rgba(0, 0, 0, 1)">
进程 </span>1<span style="color: rgba(0, 0, 0, 1)"> 执行。
子进程已退出,退出码 </span>0<span style="color: rgba(0, 0, 0, 1)">
进程 </span>2<span style="color: rgba(0, 0, 0, 1)"> 执行。
子进程已退出,退出码 </span>0</pre>
</div>
<h1>Node.js JXcore 打包</h1>
<p>Node.js 是一个开放源代码、跨平台的、用于服务器端和网络应用的运行环境。</p>
<p>JXcore 是一个支持多线程的 Node.js 发行版本,基本不需要对你现有的代码做任何改动就可以直接线程安全地以多线程运行。</p>
<p>这篇文章主要是要向大家介绍 JXcore 的打包功能。</p>
<h2>JXcore 安装</h2>
<p>下载 JXcore 安装包,并解压,在解压的的目录下提供了 jx 二进制文件命令,接下来我们主要使用这个命令。</p>
<h3>步骤1、下载</h3>
<p>下载 JXcore 安装包 https://github.com/jxcore/jxcore-release,你需要根据你自己的系统环境来下载安装包。</p>
<p>1、Window 平台下载:Download(Windows x64 (V8))。</p>
<p>2、Linux/OSX 安装命令:</p>
<div class="cnblogs_code">
<pre>curl https:<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">raw.githubusercontent.com/jxcore/jxcore/master/tools/jx_install.sh | bash</span></pre>
</div>
<p> </p>
<p>如果权限不足,可以使用以下命令:</p>
<div class="cnblogs_code">
<pre>curl https:<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">raw.githubusercontent.com/jxcore/jxcore/master/tools/jx_install.sh | sudo bash</span></pre>
</div>
<p> </p>
<p>以上步骤如果操作正确,使用以下命令,会输出版本号信息:</p>
<div class="cnblogs_code">
<pre>jx --version</pre>
</div>
<pre class="prettyprint prettyprinted"><span class="pln"><span class="pun"><span class="pln">v0<span class="pun">.<span class="lit">10.32</span></span></span></span></span></pre>
<h2>包代码</h2>
<p>例如,我们的 Node.js 项目包含以下几个文件,其中 index.js 是主文件:</p>
<div class="cnblogs_code">
<pre>drwxr-xr-x2 root root4096 Nov 13 12:42<span style="color: rgba(0, 0, 0, 1)"> images
</span>-rwxr-xr-x1 root root 30457 Mar6 12:19<span style="color: rgba(0, 0, 0, 1)"> index.htm
</span>-rwxr-xr-x1 root root 30452 Mar1 12:54<span style="color: rgba(0, 0, 0, 1)"> index.js
drwxr</span>-xr-x 23 root root4096 Jan 15 03:48<span style="color: rgba(0, 0, 0, 1)"> node_modules
drwxr</span>-xr-x2 root root4096 Mar 21 06:10<span style="color: rgba(0, 0, 0, 1)"> scripts
drwxr</span>-xr-x2 root root4096 Feb 15 11:56 style</pre>
</div>
<p> </p>
<p>接下来我们使用 <strong>jx</strong> 命令打包以上项目,并指定 index.js 为 Node.js 项目的主文件:</p>
<div class="cnblogs_code">
<pre> jx package index.js index</pre>
</div>
<p> </p>
<p>以上命令执行成功,会生成以下两个文件:</p>
<ul>
<li>
<p><strong>index.jxp</strong> 这是一个中间件文件,包含了需要编译的完整项目信息。</p>
</li>
<li>
<p><strong>index.jx</strong> 这是一个完整包信息的二进制文件,可运行在客户端上。</p>
</li>
</ul>
<h2>载入 JX 文件</h2>
<p>Node.js 的项目运行:</p>
<div class="cnblogs_code">
<pre>node index.js command_line_arguments</pre>
</div>
<p> </p>
<p>使用 JXcore 编译后,我们可以使用以下命令来执行生成的 jx 二进制文件:</p>
<div class="cnblogs_code">
<pre>jx index.jx command_line_arguments</pre>
</div>
<p> </p>
<p>更多 JXcore 安装参考:https://github.com/jxcore/jxcore/blob/master/doc/INSTALLATION.md。</p>
<p>更多 JXcore 功能特性你可以参考官网:https://github.com/jxcore/jxcore。</p>
<h1>Node.js 连接 MySQL</h1>
<p>本章节我们将为大家介绍如何使用 Node.js 来连接 MySQL,并对数据库进行操作。</p>
<p>如果你还没有 MySQL 的基本知识,可以参考我们的教程:MySQL 教程。</p>
<p>本教程使用到的 Websites 表 SQL 文件:websites.sql。</p>
<h3>安装驱动</h3>
<p>本教程使用了淘宝定制的 cnpm 命令进行安装:</p>
<div class="cnblogs_code">
<pre>cnpm install mysql</pre>
</div>
<p> </p>
<h3>连接数据库</h3>
<p>在以下实例中根据你的实际配置修改数据库用户名、及密码及数据库名:</p>
<div class="example">
<h2 class="example">test.js 文件代码:</h2>
<div class="example_code">
<div class="hl-main">
<div class="cnblogs_code"><img id="code_img_closed_f1990c6e-d26f-4957-98da-86959bacf9cb" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_f1990c6e-d26f-4957-98da-86959bacf9cb" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_f1990c6e-d26f-4957-98da-86959bacf9cb" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> mysql = require('mysql'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> connection =<span style="color: rgba(0, 0, 0, 1)"> mysql.createConnection({
host : </span>'localhost'<span style="color: rgba(0, 0, 0, 1)">,
user : </span>'root'<span style="color: rgba(0, 0, 0, 1)">,
password : </span>'123456'<span style="color: rgba(0, 0, 0, 1)">,
database : </span>'test'<span style="color: rgba(0, 0, 0, 1)">
});
connection.connect();
connection.query(</span>'SELECT 1 + 1 AS solution', <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> (error, results, fields) {
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (error) <span style="color: rgba(0, 0, 255, 1)">throw</span><span style="color: rgba(0, 0, 0, 1)"> error;
console.log(</span>'The solution is: ', results.solution);
});</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
</div>
</div>
<p>执行以下命令输出结果为:</p>
<div class="example_code">
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">node test.js
The solution is: </span>2</pre>
</div>
</div>
</div>
<h3>数据库连接参数说明:</h3>
<table class="reference">
<tbody>
<tr><th>参数</th><th>描述</th></tr>
<tr>
<td>host</td>
<td>主机地址 (默认:localhost)</td>
</tr>
<tr>
<td> user</td>
<td>用户名</td>
</tr>
<tr>
<td> password</td>
<td>密码</td>
</tr>
<tr>
<td> port</td>
<td>端口号 (默认:3306)</td>
</tr>
<tr>
<td> database</td>
<td>数据库名</td>
</tr>
<tr>
<td> charset</td>
<td>连接字符集(默认:'UTF8_GENERAL_CI',注意字符集的字母都要大写)</td>
</tr>
<tr>
<td> localAddress</td>
<td>此IP用于TCP连接(可选)</td>
</tr>
<tr>
<td> socketPath</td>
<td>连接到unix域路径,当使用 host 和 port 时会被忽略</td>
</tr>
<tr>
<td> timezone</td>
<td>时区(默认:'local')</td>
</tr>
<tr>
<td> connectTimeout</td>
<td>连接超时(默认:不限制;单位:毫秒)</td>
</tr>
<tr>
<td> stringifyObjects</td>
<td>是否序列化对象</td>
</tr>
<tr>
<td> typeCast</td>
<td>是否将列值转化为本地JavaScript类型值 (默认:true)</td>
</tr>
<tr>
<td> queryFormat</td>
<td>自定义query语句格式化方法</td>
</tr>
<tr>
<td> supportBigNumbers</td>
<td>数据库支持bigint或decimal类型列时,需要设此option为true (默认:false)</td>
</tr>
<tr>
<td> bigNumberStrings</td>
<td>supportBigNumbers和bigNumberStrings启用 强制bigint或decimal列以JavaScript字符串类型返回(默认:false)</td>
</tr>
<tr>
<td> dateStrings</td>
<td>强制timestamp,datetime,data类型以字符串类型返回,而不是JavaScript Date类型(默认:false)</td>
</tr>
<tr>
<td> debug</td>
<td>开启调试(默认:false)</td>
</tr>
<tr>
<td> multipleStatements</td>
<td>是否许一个query中有多个MySQL语句 (默认:false)</td>
</tr>
<tr>
<td> flags</td>
<td>用于修改连接标志</td>
</tr>
<tr>
<td> ssl</td>
<td>使用ssl参数(与crypto.createCredenitals参数格式一至)或一个包含ssl配置文件名称的字符串,目前只捆绑Amazon RDS的配置文件</td>
</tr>
</tbody>
</table>
<p>更多说明可参见:https://github.com/mysqljs/mysql</p>
<hr>
<h2>数据库操作( CURD )</h2>
<p>在进行数据库操作前,你需要将本站提供的 Websites 表 SQL 文件websites.sql 导入到你的 MySQL 数据库中。</p>
<p>本教程测试的 MySQL 用户名为 root,密码为 123456,数据库为 test,你需要根据自己配置情况修改。</p>
<h3>查询数据</h3>
<p>将上面我们提供的 SQL 文件导入数据库后,执行以下代码即可查询出数据:</p>
<div class="example">
<h2 class="example">查询数据</h2>
<div class="example_code">
<div class="hl-main">
<div class="cnblogs_code"><img id="code_img_closed_d64b66af-1e55-4e60-a2b7-96511214e7a3" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_d64b66af-1e55-4e60-a2b7-96511214e7a3" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_d64b66af-1e55-4e60-a2b7-96511214e7a3" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> mysql= require('mysql'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> connection =<span style="color: rgba(0, 0, 0, 1)"> mysql.createConnection({
host : </span>'localhost'<span style="color: rgba(0, 0, 0, 1)">,
user : </span>'root'<span style="color: rgba(0, 0, 0, 1)">,
password : </span>'123456'<span style="color: rgba(0, 0, 0, 1)">,
port: </span>'3306'<span style="color: rgba(0, 0, 0, 1)">,
database: </span>'test'<span style="color: rgba(0, 0, 0, 1)">
});
connection.connect();
</span><span style="color: rgba(0, 0, 255, 1)">var</span>sql = 'SELECT * FROM websites'<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">查</span>
connection.query(sql,<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> (err, result) {
</span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)">(err){
console.log(</span>' - '<span style="color: rgba(0, 0, 0, 1)">,err.message);
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)">;
}
console.log(</span>'--------------------------SELECT----------------------------'<span style="color: rgba(0, 0, 0, 1)">);
console.log(result);
console.log(</span>'------------------------------------------------------------\n\n'<span style="color: rgba(0, 0, 0, 1)">);
});
connection.end();</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
</div>
</div>
<p>执行以下命令输出就结果为:</p>
<div class="example_code">
<div class="cnblogs_code"><img id="code_img_closed_c977ecc0-7d45-44a2-b098-b4ae796db421" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_c977ecc0-7d45-44a2-b098-b4ae796db421" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_c977ecc0-7d45-44a2-b098-b4ae796db421" class="cnblogs_code_hide">
<pre>--------------------------SELECT----------------------------<span style="color: rgba(0, 0, 0, 1)">
[ RowDataPacket {
id: </span>1<span style="color: rgba(0, 0, 0, 1)">,
name: </span>'Google'<span style="color: rgba(0, 0, 0, 1)">,
url: </span>'https://www.google.cm/'<span style="color: rgba(0, 0, 0, 1)">,
alexa: </span>1<span style="color: rgba(0, 0, 0, 1)">,
country: </span>'USA'<span style="color: rgba(0, 0, 0, 1)"> },
RowDataPacket {
id: </span>2<span style="color: rgba(0, 0, 0, 1)">,
name: </span>'淘宝'<span style="color: rgba(0, 0, 0, 1)">,
url: </span>'https://www.taobao.com/'<span style="color: rgba(0, 0, 0, 1)">,
alexa: </span>13<span style="color: rgba(0, 0, 0, 1)">,
country: </span>'CN'<span style="color: rgba(0, 0, 0, 1)"> },
RowDataPacket {
id: </span>3<span style="color: rgba(0, 0, 0, 1)">,
name: </span>'菜鸟教程'<span style="color: rgba(0, 0, 0, 1)">,
url: </span>'http://www.runoob.com/'<span style="color: rgba(0, 0, 0, 1)">,
alexa: </span>4689<span style="color: rgba(0, 0, 0, 1)">,
country: </span>'CN'<span style="color: rgba(0, 0, 0, 1)"> },
RowDataPacket {
id: </span>4<span style="color: rgba(0, 0, 0, 1)">,
name: </span>'微博'<span style="color: rgba(0, 0, 0, 1)">,
url: </span>'http://weibo.com/'<span style="color: rgba(0, 0, 0, 1)">,
alexa: </span>20<span style="color: rgba(0, 0, 0, 1)">,
country: </span>'CN'<span style="color: rgba(0, 0, 0, 1)"> },
RowDataPacket {
id: </span>5<span style="color: rgba(0, 0, 0, 1)">,
name: </span>'Facebook'<span style="color: rgba(0, 0, 0, 1)">,
url: </span>'https://www.facebook.com/'<span style="color: rgba(0, 0, 0, 1)">,
alexa: </span>3<span style="color: rgba(0, 0, 0, 1)">,
country: </span>'USA'<span style="color: rgba(0, 0, 0, 1)"> } ]
</span>------------------------------------------------------------</pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p> </p>
</div>
</div>
<h3>插入数据</h3>
<p>我们可以向数据表 websties 插入数据:</p>
<div class="example">
<h2 class="example">插入数据</h2>
<div class="example_code">
<div class="hl-main">
<div class="cnblogs_code"><img id="code_img_closed_a0144200-6b66-43cd-a714-101938263100" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_a0144200-6b66-43cd-a714-101938263100" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_a0144200-6b66-43cd-a714-101938263100" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> mysql= require('mysql'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> connection =<span style="color: rgba(0, 0, 0, 1)"> mysql.createConnection({
host : </span>'localhost'<span style="color: rgba(0, 0, 0, 1)">,
user : </span>'root'<span style="color: rgba(0, 0, 0, 1)">,
password : </span>'123456'<span style="color: rgba(0, 0, 0, 1)">,
port: </span>'3306'<span style="color: rgba(0, 0, 0, 1)">,
database: </span>'test'<span style="color: rgba(0, 0, 0, 1)">
});
connection.connect();
</span><span style="color: rgba(0, 0, 255, 1)">var</span>addSql = 'INSERT INTO websites(Id,name,url,alexa,country) VALUES(0,?,?,?,?)'<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">var</span>addSqlParams = ['菜鸟工具', 'https://c.runoob.com','23453', 'CN'<span style="color: rgba(0, 0, 0, 1)">];
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">增</span>
connection.query(addSql,addSqlParams,<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> (err, result) {
</span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)">(err){
console.log(</span>' - '<span style="color: rgba(0, 0, 0, 1)">,err.message);
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)">;
}
console.log(</span>'--------------------------INSERT----------------------------'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">console.log('INSERT ID:',result.insertId); </span>
console.log('INSERT ID:'<span style="color: rgba(0, 0, 0, 1)">,result);
console.log(</span>'-----------------------------------------------------------------\n\n'<span style="color: rgba(0, 0, 0, 1)">);
});
connection.end();</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
</div>
</div>
<p>执行以下命令输出就结果为:</p>
<div class="example_code">
<div class="cnblogs_code"><img id="code_img_closed_67f6f781-2ec9-47c6-820d-f2bb1a4e06b4" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_67f6f781-2ec9-47c6-820d-f2bb1a4e06b4" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_67f6f781-2ec9-47c6-820d-f2bb1a4e06b4" class="cnblogs_code_hide">
<pre>--------------------------INSERT----------------------------<span style="color: rgba(0, 0, 0, 1)">
INSERT ID: OkPacket {
fieldCount: </span>0<span style="color: rgba(0, 0, 0, 1)">,
affectedRows: </span>1<span style="color: rgba(0, 0, 0, 1)">,
insertId: </span>6<span style="color: rgba(0, 0, 0, 1)">,
serverStatus: </span>2<span style="color: rgba(0, 0, 0, 1)">,
warningCount: </span>0<span style="color: rgba(0, 0, 0, 1)">,
message: </span>''<span style="color: rgba(0, 0, 0, 1)">,
protocol41: </span><span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">,
changedRows: </span>0<span style="color: rgba(0, 0, 0, 1)"> }
</span>-----------------------------------------------------------------</pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p> </p>
</div>
</div>
<p>执行成功后,查看数据表,即可以看到添加的数据:</p>
<p><img src="https://www.runoob.com/wp-content/uploads/2017/03/1E2D27C5-45F3-4E57-90D3-4AE35AEB17F7.jpg" alt=""></p>
<h3>更新数据</h3>
<p>我们也可以对数据库的数据进行修改:</p>
<div class="example">
<h2 class="example">更新数据</h2>
<div class="example_code">
<div class="hl-main">
<div class="cnblogs_code"><img id="code_img_closed_1a151ead-ce22-427b-83f6-27cad2dcaa76" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_1a151ead-ce22-427b-83f6-27cad2dcaa76" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_1a151ead-ce22-427b-83f6-27cad2dcaa76" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> mysql= require('mysql'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> connection =<span style="color: rgba(0, 0, 0, 1)"> mysql.createConnection({
host : </span>'localhost'<span style="color: rgba(0, 0, 0, 1)">,
user : </span>'root'<span style="color: rgba(0, 0, 0, 1)">,
password : </span>'123456'<span style="color: rgba(0, 0, 0, 1)">,
port: </span>'3306'<span style="color: rgba(0, 0, 0, 1)">,
database: </span>'test'<span style="color: rgba(0, 0, 0, 1)">
});
connection.connect();
</span><span style="color: rgba(0, 0, 255, 1)">var</span> modSql = 'UPDATE websites SET name = ?,url = ? WHERE Id = ?'<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">var</span> modSqlParams = ['菜鸟移动站', 'https://m.runoob.com',6<span style="color: rgba(0, 0, 0, 1)">];
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">改</span>
connection.query(modSql,modSqlParams,<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> (err, result) {
</span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)">(err){
console.log(</span>' - '<span style="color: rgba(0, 0, 0, 1)">,err.message);
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)">;
}
console.log(</span>'--------------------------UPDATE----------------------------'<span style="color: rgba(0, 0, 0, 1)">);
console.log(</span>'UPDATE affectedRows'<span style="color: rgba(0, 0, 0, 1)">,result.affectedRows);
console.log(</span>'-----------------------------------------------------------------\n\n'<span style="color: rgba(0, 0, 0, 1)">);
});
connection.end();</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
</div>
</div>
<p>执行以下命令输出就结果为:</p>
<div class="example_code">
<div class="cnblogs_code">
<pre>--------------------------UPDATE----------------------------<span style="color: rgba(0, 0, 0, 1)">
UPDATE affectedRows </span>1
-----------------------------------------------------------------</pre>
</div>
<p> </p>
</div>
</div>
<p>执行成功后,查看数据表,即可以看到更新的数据:</p>
<p><img src="https://www.runoob.com/wp-content/uploads/2017/03/A5C8911B-E07B-48DD-9C3E-28F1E73A1A30.jpg" alt=""></p>
<h3>删除数据</h3>
<p>我们可以使用以下代码来删除 id 为 6 的数据:</p>
<div class="example">
<h2 class="example">删除数据</h2>
<div class="example_code">
<div class="hl-main">
<div class="cnblogs_code"><img id="code_img_closed_1ef0adba-93ff-4018-9faa-0c5cf736c972" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_1ef0adba-93ff-4018-9faa-0c5cf736c972" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_1ef0adba-93ff-4018-9faa-0c5cf736c972" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> mysql= require('mysql'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> connection =<span style="color: rgba(0, 0, 0, 1)"> mysql.createConnection({
host : </span>'localhost'<span style="color: rgba(0, 0, 0, 1)">,
user : </span>'root'<span style="color: rgba(0, 0, 0, 1)">,
password : </span>'123456'<span style="color: rgba(0, 0, 0, 1)">,
port: </span>'3306'<span style="color: rgba(0, 0, 0, 1)">,
database: </span>'test'<span style="color: rgba(0, 0, 0, 1)">
});
connection.connect();
</span><span style="color: rgba(0, 0, 255, 1)">var</span> delSql = 'DELETE FROM websites where id=6'<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">删</span>
connection.query(delSql,<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> (err, result) {
</span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)">(err){
console.log(</span>' - '<span style="color: rgba(0, 0, 0, 1)">,err.message);
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)">;
}
console.log(</span>'--------------------------DELETE----------------------------'<span style="color: rgba(0, 0, 0, 1)">);
console.log(</span>'DELETE affectedRows'<span style="color: rgba(0, 0, 0, 1)">,result.affectedRows);
console.log(</span>'-----------------------------------------------------------------\n\n'<span style="color: rgba(0, 0, 0, 1)">);
});
connection.end();</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
</div>
</div>
<p>执行以下命令输出就结果为:</p>
<div class="example_code">
<div class="cnblogs_code">
<pre>--------------------------DELETE----------------------------<span style="color: rgba(0, 0, 0, 1)">
DELETE affectedRows </span>1
-----------------------------------------------------------------</pre>
</div>
<p> </p>
</div>
</div>
<p>执行成功后,查看数据表,即可以看到 id=6 的数据已被删除:</p>
<p><img src="https://www.runoob.com/wp-content/uploads/2017/03/27BEB36A-0DCE-4C75-961F-93D55CBECC54.jpg" alt=""></p>
<p> </p>
<div class="article-body">
<div id="content" class="article-intro">
<h1>Node.js 连接 MongoDB</h1>
<p>MongoDB是一种文档导向数据库管理系统,由C++撰写而成。</p>
<p>本章节我们将为大家介绍如何使用 Node.js 来连接 MongoDB,并对数据库进行操作。</p>
<p>如果你还没有 MongoDB 的基本知识,可以参考我们的教程:MongoDB 教程。</p>
<h3>安装驱动</h3>
<p>本教程使用了淘宝定制的 cnpm 命令进行安装:</p>
<div class="cnblogs_code">
<pre>cnpm install mongodb</pre>
</div>
<p>接下来我们来实现增删改查功能。</p>
<h2>创建数据库</h2>
<p>要在 MongoDB 中创建一个数据库,首先我们需要创建一个 MongoClient 对象,然后配置好指定的 URL 和 端口号。</p>
<p>如果数据库不存在,MongoDB 将创建数据库并建立连接。</p>
<div class="example">
<h2 class="example">创建连接</h2>
<div class="example_code">
<div class="hl-main">
<div class="cnblogs_code"><img id="code_img_closed_7ec66f0e-394f-4400-aa81-57d3becc3be6" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_7ec66f0e-394f-4400-aa81-57d3becc3be6" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_7ec66f0e-394f-4400-aa81-57d3becc3be6" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> MongoClient = require('mongodb'<span style="color: rgba(0, 0, 0, 1)">).MongoClient;
</span><span style="color: rgba(0, 0, 255, 1)">var</span> url = "mongodb://localhost:27017/runoob"<span style="color: rgba(0, 0, 0, 1)">;
MongoClient.connect(url, { useNewUrlParser: </span><span style="color: rgba(0, 0, 255, 1)">true</span> }, <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(err, db) {
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (err) <span style="color: rgba(0, 0, 255, 1)">throw</span><span style="color: rgba(0, 0, 0, 1)"> err;
console.log(</span>"数据库已创建!"<span style="color: rgba(0, 0, 0, 1)">);
db.close();
});</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
</div>
</div>
</div>
<h2>创建集合</h2>
<p>我们可以使用 createCollection() 方法来创建集合:</p>
<div class="example">
<h2 class="example">创建集合</h2>
<div class="example_code">
<div class="hl-main">
<div class="cnblogs_code"><img id="code_img_closed_fa8c62f8-dd54-4ad3-af09-ed6c98b60d35" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_fa8c62f8-dd54-4ad3-af09-ed6c98b60d35" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_fa8c62f8-dd54-4ad3-af09-ed6c98b60d35" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> MongoClient = require('mongodb'<span style="color: rgba(0, 0, 0, 1)">).MongoClient;
</span><span style="color: rgba(0, 0, 255, 1)">var</span> url = 'mongodb://localhost:27017/runoob'<span style="color: rgba(0, 0, 0, 1)">;
MongoClient.connect(url, { useNewUrlParser: </span><span style="color: rgba(0, 0, 255, 1)">true</span> }, <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> (err, db) {
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (err) <span style="color: rgba(0, 0, 255, 1)">throw</span><span style="color: rgba(0, 0, 0, 1)"> err;
console.log(</span>'数据库已创建'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> dbase = db.db("runoob"<span style="color: rgba(0, 0, 0, 1)">);
dbase.createCollection(</span>'site', <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> (err, res) {
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (err) <span style="color: rgba(0, 0, 255, 1)">throw</span><span style="color: rgba(0, 0, 0, 1)"> err;
console.log(</span>"创建集合!"<span style="color: rgba(0, 0, 0, 1)">);
db.close();
});
});</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
</div>
</div>
</div>
<h2>数据库操作( CURD )</h2>
<p>与 MySQL 不同的是 MongoDB 会自动创建数据库和集合,所以使用前我们不需要手动去创建。</p>
<h3>插入数据</h3>
<p>以下实例我们连接数据库 runoob 的 site 表,并插入一条数据条数据,使用<span class="marked"> insertOne():</span></p>
<div class="example">
<h2 class="example">插入一条数据</h2>
<div class="example_code">
<div class="hl-main">
<div class="cnblogs_code"><img id="code_img_closed_9ad081fa-de12-4c7f-b1d0-091d0284fb05" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_9ad081fa-de12-4c7f-b1d0-091d0284fb05" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_9ad081fa-de12-4c7f-b1d0-091d0284fb05" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> MongoClient = require('mongodb'<span style="color: rgba(0, 0, 0, 1)">).MongoClient;
</span><span style="color: rgba(0, 0, 255, 1)">var</span> url = "mongodb://localhost:27017/"<span style="color: rgba(0, 0, 0, 1)">;
MongoClient.connect(url, { useNewUrlParser: </span><span style="color: rgba(0, 0, 255, 1)">true</span> }, <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(err, db) {
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (err) <span style="color: rgba(0, 0, 255, 1)">throw</span><span style="color: rgba(0, 0, 0, 1)"> err;
</span><span style="color: rgba(0, 0, 255, 1)">var</span> dbo = db.db("runoob"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> myobj = { name: "菜鸟教程", url: "www.runoob"<span style="color: rgba(0, 0, 0, 1)"> };
dbo.collection(</span>"site").insertOne(myobj, <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(err, res) {
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (err) <span style="color: rgba(0, 0, 255, 1)">throw</span><span style="color: rgba(0, 0, 0, 1)"> err;
console.log(</span>"文档插入成功"<span style="color: rgba(0, 0, 0, 1)">);
db.close();
});
});</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
</div>
</div>
<p>执行以下命令输出就结果为:</p>
<div class="example_code">
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">node test.js
文档插入成功</span></pre>
</div>
</div>
</div>
<p>从输出结果来看,数据已插入成功。</p>
<p>我们也可以打开 MongoDB 的客户端查看数据,如:</p>
<div class="cnblogs_code"><img id="code_img_closed_4c451b6c-7e4c-4475-a268-a7411fab363c" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_4c451b6c-7e4c-4475-a268-a7411fab363c" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_4c451b6c-7e4c-4475-a268-a7411fab363c" class="cnblogs_code_hide">
<pre>><span style="color: rgba(0, 0, 0, 1)"> show dbs
runoob</span>0<span style="color: rgba(0, 0, 0, 1)">.000GB # 自动创建了 runoob 数据库
</span>><span style="color: rgba(0, 0, 0, 1)"> show tables
site # 自动创建了 site 集合(数据表)
</span>><span style="color: rgba(0, 0, 0, 1)"> db.site.find()
{ </span>"_id" : ObjectId("5a794e36763eb821b24db854"), "name" : "菜鸟教程", "url" : "www.runoob"<span style="color: rgba(0, 0, 0, 1)"> }
</span>></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p>如果要插入多条数据可以使用 <span class="marked">insertMany():</span></p>
<div class="example">
<h2 class="example">插入多条数据</h2>
<div class="example_code">
<div class="hl-main">
<div class="cnblogs_code"><img id="code_img_closed_cbab8bd4-6a2c-4026-afdf-94e9d1757478" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_cbab8bd4-6a2c-4026-afdf-94e9d1757478" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_cbab8bd4-6a2c-4026-afdf-94e9d1757478" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> MongoClient = require('mongodb'<span style="color: rgba(0, 0, 0, 1)">).MongoClient;
</span><span style="color: rgba(0, 0, 255, 1)">var</span> url = "mongodb://localhost:27017/"<span style="color: rgba(0, 0, 0, 1)">;
MongoClient.connect(url, { useNewUrlParser: </span><span style="color: rgba(0, 0, 255, 1)">true</span> }, <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(err, db) {
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (err) <span style="color: rgba(0, 0, 255, 1)">throw</span><span style="color: rgba(0, 0, 0, 1)"> err;
</span><span style="color: rgba(0, 0, 255, 1)">var</span> dbo = db.db("runoob"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> myobj =<span style="color: rgba(0, 0, 0, 1)">[
{ name: </span>'菜鸟工具', url: 'https://c.runoob.com', type: 'cn'<span style="color: rgba(0, 0, 0, 1)">},
{ name: </span>'Google', url: 'https://www.google.com', type: 'en'<span style="color: rgba(0, 0, 0, 1)">},
{ name: </span>'Facebook', url: 'https://www.google.com', type: 'en'<span style="color: rgba(0, 0, 0, 1)">}
];
dbo.collection(</span>"site").insertMany(myobj, <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(err, res) {
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (err) <span style="color: rgba(0, 0, 255, 1)">throw</span><span style="color: rgba(0, 0, 0, 1)"> err;
console.log(</span>"插入的文档数量为: " +<span style="color: rgba(0, 0, 0, 1)"> res.insertedCount);
db.close();
});
});</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
</div>
</div>
</div>
<h3>查询数据</h3>
<p>可以使用 find() 来查找数据, find() 可以返回匹配条件的所有数据。 如果未指定条件,find() 返回集合中的所有数据。</p>
<div class="example">
<h2 class="example">find()</h2>
<div class="example_code">
<div class="hl-main">
<div class="cnblogs_code"><img id="code_img_closed_45f3881c-99d4-44eb-80d4-aef04aff672f" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_45f3881c-99d4-44eb-80d4-aef04aff672f" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_45f3881c-99d4-44eb-80d4-aef04aff672f" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> MongoClient = require('mongodb'<span style="color: rgba(0, 0, 0, 1)">).MongoClient;
</span><span style="color: rgba(0, 0, 255, 1)">var</span> url = "mongodb://localhost:27017/"<span style="color: rgba(0, 0, 0, 1)">;
MongoClient.connect(url, { useNewUrlParser: </span><span style="color: rgba(0, 0, 255, 1)">true</span> }, <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(err, db) {
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (err) <span style="color: rgba(0, 0, 255, 1)">throw</span><span style="color: rgba(0, 0, 0, 1)"> err;
</span><span style="color: rgba(0, 0, 255, 1)">var</span> dbo = db.db("runoob"<span style="color: rgba(0, 0, 0, 1)">);
dbo.collection(</span>"site"). find({}).toArray(<span style="color: rgba(0, 0, 255, 1)">function</span>(err, result) { <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 返回集合中所有数据</span>
<span style="color: rgba(0, 0, 255, 1)">if</span> (err) <span style="color: rgba(0, 0, 255, 1)">throw</span><span style="color: rgba(0, 0, 0, 1)"> err;
console.log(result);
db.close();
});
});</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
</div>
</div>
</div>
<p>以下实例检索 name 为 "菜鸟教程" 的实例:</p>
<div class="example">
<h2 class="example">查询指定条件的数据</h2>
<div class="example_code">
<div class="hl-main">
<div class="cnblogs_code"><img id="code_img_closed_6f37ebaf-01c0-48ab-be16-a46d5b1068b8" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_6f37ebaf-01c0-48ab-be16-a46d5b1068b8" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_6f37ebaf-01c0-48ab-be16-a46d5b1068b8" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> MongoClient = require('mongodb'<span style="color: rgba(0, 0, 0, 1)">).MongoClient;
</span><span style="color: rgba(0, 0, 255, 1)">var</span> url = "mongodb://localhost:27017/"<span style="color: rgba(0, 0, 0, 1)">;
MongoClient.connect(url, { useNewUrlParser: </span><span style="color: rgba(0, 0, 255, 1)">true</span> }, <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(err, db) {
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (err) <span style="color: rgba(0, 0, 255, 1)">throw</span><span style="color: rgba(0, 0, 0, 1)"> err;
</span><span style="color: rgba(0, 0, 255, 1)">var</span> dbo = db.db("runoob"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> whereStr = {"name":'菜鸟教程'};<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 查询条件</span>
dbo.collection("site").find(whereStr).toArray(<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(err, result) {
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (err) <span style="color: rgba(0, 0, 255, 1)">throw</span><span style="color: rgba(0, 0, 0, 1)"> err;
console.log(result);
db.close();
});
});</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
</div>
<div class="hl-main"><span class="hl-reserved">执行以下命令输出就结果为:</span></div>
</div>
<div class="example_code">
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">[ { _id: 5a794e36763eb821b24db854,
name: </span>'菜鸟教程'<span style="color: rgba(0, 0, 0, 1)">,
url: </span>'www.runoob' } ]</pre>
</div>
</div>
</div>
<h3>更新数据</h3>
<p>我们也可以对数据库的数据进行修改,以下实例将 name 为 "菜鸟教程" 的 url 改为 https://www.runoob.com:</p>
<div class="example">
<h2 class="example">更新一条数据</h2>
<div class="example_code">
<div class="hl-main">
<div class="cnblogs_code"><img id="code_img_closed_ee8b447d-f970-4673-b533-db4a7b20ad48" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_ee8b447d-f970-4673-b533-db4a7b20ad48" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_ee8b447d-f970-4673-b533-db4a7b20ad48" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> MongoClient = require('mongodb'<span style="color: rgba(0, 0, 0, 1)">).MongoClient;
</span><span style="color: rgba(0, 0, 255, 1)">var</span> url = "mongodb://localhost:27017/"<span style="color: rgba(0, 0, 0, 1)">;
MongoClient.connect(url, { useNewUrlParser: </span><span style="color: rgba(0, 0, 255, 1)">true</span> }, <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(err, db) {
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (err) <span style="color: rgba(0, 0, 255, 1)">throw</span><span style="color: rgba(0, 0, 0, 1)"> err;
</span><span style="color: rgba(0, 0, 255, 1)">var</span> dbo = db.db("runoob"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> whereStr = {"name":'菜鸟教程'};<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 查询条件</span>
<span style="color: rgba(0, 0, 255, 1)">var</span> updateStr = {$set: { "url" : "https://www.runoob.com"<span style="color: rgba(0, 0, 0, 1)"> }};
dbo.collection(</span>"site").updateOne(whereStr, updateStr, <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(err, res) {
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (err) <span style="color: rgba(0, 0, 255, 1)">throw</span><span style="color: rgba(0, 0, 0, 1)"> err;
console.log(</span>"文档更新成功"<span style="color: rgba(0, 0, 0, 1)">);
db.close();
});
});</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
</div>
</div>
<p>执行成功后,进入 mongo 管理工具查看数据已修改:</p>
<div class="example_code">
<div class="cnblogs_code">
<pre>><span style="color: rgba(0, 0, 0, 1)"> db.site.find().pretty()
{
</span>"_id" : ObjectId("5a794e36763eb821b24db854"<span style="color: rgba(0, 0, 0, 1)">),
</span>"name" : "菜鸟教程"<span style="color: rgba(0, 0, 0, 1)">,
</span>"url" : "https://www.runoob.com" <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 已修改为 https</span>
}</pre>
</div>
<p> </p>
</div>
</div>
<p>如果要更新所有符合条的文档数据可以使用 <span class="marked">updateMany():</span></p>
<div class="example">
<h2 class="example">更新多条数据</h2>
<div class="example_code">
<div class="hl-main">
<div class="cnblogs_code"><img id="code_img_closed_3123c5a7-8064-4c9c-9d9a-331a60859fba" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_3123c5a7-8064-4c9c-9d9a-331a60859fba" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_3123c5a7-8064-4c9c-9d9a-331a60859fba" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> MongoClient = require('mongodb'<span style="color: rgba(0, 0, 0, 1)">).MongoClient;
</span><span style="color: rgba(0, 0, 255, 1)">var</span> url = "mongodb://localhost:27017/"<span style="color: rgba(0, 0, 0, 1)">;
MongoClient.connect(url, { useNewUrlParser: </span><span style="color: rgba(0, 0, 255, 1)">true</span> }, <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(err, db) {
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (err) <span style="color: rgba(0, 0, 255, 1)">throw</span><span style="color: rgba(0, 0, 0, 1)"> err;
</span><span style="color: rgba(0, 0, 255, 1)">var</span> dbo = db.db("runoob"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> whereStr = {"type":'en'};<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 查询条件</span>
<span style="color: rgba(0, 0, 255, 1)">var</span> updateStr = {$set: { "url" : "https://www.runoob.com"<span style="color: rgba(0, 0, 0, 1)"> }};
dbo.collection(</span>"site").updateMany(whereStr, updateStr, <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(err, res) {
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (err) <span style="color: rgba(0, 0, 255, 1)">throw</span><span style="color: rgba(0, 0, 0, 1)"> err;
console.log(res.result.nModified </span>+ " 条文档被更新"<span style="color: rgba(0, 0, 0, 1)">);
db.close();
});
});</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
</div>
</div>
</div>
<p>result.nModified 为更新的条数。</p>
<h3>删除数据</h3>
<p>以下实例将 name 为 "菜鸟教程" 的数据删除 :</p>
<div class="example">
<h2 class="example">删除一条数据</h2>
<div class="example_code">
<div class="hl-main">
<div class="cnblogs_code"><img id="code_img_closed_c0696315-5ed0-4231-9590-b37f5d120cbb" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_c0696315-5ed0-4231-9590-b37f5d120cbb" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_c0696315-5ed0-4231-9590-b37f5d120cbb" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> MongoClient = require('mongodb'<span style="color: rgba(0, 0, 0, 1)">).MongoClient;
</span><span style="color: rgba(0, 0, 255, 1)">var</span> url = "mongodb://localhost:27017/"<span style="color: rgba(0, 0, 0, 1)">;
MongoClient.connect(url, { useNewUrlParser: </span><span style="color: rgba(0, 0, 255, 1)">true</span> }, <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(err, db) {
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (err) <span style="color: rgba(0, 0, 255, 1)">throw</span><span style="color: rgba(0, 0, 0, 1)"> err;
</span><span style="color: rgba(0, 0, 255, 1)">var</span> dbo = db.db("runoob"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> whereStr = {"name":'菜鸟教程'};<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 查询条件</span>
dbo.collection("site").deleteOne(whereStr, <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(err, obj) {
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (err) <span style="color: rgba(0, 0, 255, 1)">throw</span><span style="color: rgba(0, 0, 0, 1)"> err;
console.log(</span>"文档删除成功"<span style="color: rgba(0, 0, 0, 1)">);
db.close();
});
});</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
</div>
<div class="hl-main"><span class="hl-reserved">执行成功后,进入 mongo 管理工具查看数据已删除:</span></div>
</div>
<div class="example_code">
<div class="cnblogs_code">
<pre>><span style="color: rgba(0, 0, 0, 1)"> db.site.find()<br></span>></pre>
</div>
</div>
</div>
<p>如果要删除多条语句可以使用 <span class="marked">deleteMany() 方法</span></p>
<p>以下实例将 type 为 en 的所有数据删除 :</p>
<div class="example">
<h2 class="example">删除多条数据</h2>
<div class="example_code">
<div class="hl-main">
<div class="cnblogs_code"><img id="code_img_closed_6dc53cc8-77ea-47af-a54c-e10a58cde21a" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_6dc53cc8-77ea-47af-a54c-e10a58cde21a" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_6dc53cc8-77ea-47af-a54c-e10a58cde21a" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> MongoClient = require('mongodb'<span style="color: rgba(0, 0, 0, 1)">).MongoClient;
</span><span style="color: rgba(0, 0, 255, 1)">var</span> url = "mongodb://localhost:27017/"<span style="color: rgba(0, 0, 0, 1)">;
MongoClient.connect(url, { useNewUrlParser: </span><span style="color: rgba(0, 0, 255, 1)">true</span> }, <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(err, db) {
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (err) <span style="color: rgba(0, 0, 255, 1)">throw</span><span style="color: rgba(0, 0, 0, 1)"> err;
</span><span style="color: rgba(0, 0, 255, 1)">var</span> dbo = db.db("runoob"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> whereStr = { type: "en" };<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 查询条件</span>
dbo.collection("site").deleteMany(whereStr, <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(err, obj) {
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (err) <span style="color: rgba(0, 0, 255, 1)">throw</span><span style="color: rgba(0, 0, 0, 1)"> err;
console.log(obj.result.n </span>+ " 条文档被删除"<span style="color: rgba(0, 0, 0, 1)">);
db.close();
});
});</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
</div>
</div>
</div>
<p>obj.result.n 删除的条数。</p>
<h3>排序</h3>
<p>排序 使用 sort() 方法,该方法接受一个参数,规定是升序(1)还是降序(-1)。</p>
<p>例如:</p>
<div class="cnblogs_code">
<pre>{ type: 1 }<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 按 type 字段升序</span>
{ type: -1 } <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 按 type 字段降序</span></pre>
</div>
<p>按 type 升序排列:</p>
<div class="example">
<h2 class="example">排序</h2>
<div class="cnblogs_code"><img id="code_img_closed_45444d0e-5b8b-4c2e-a5f8-95e3090f06c2" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_45444d0e-5b8b-4c2e-a5f8-95e3090f06c2" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_45444d0e-5b8b-4c2e-a5f8-95e3090f06c2" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> MongoClient = require('mongodb'<span style="color: rgba(0, 0, 0, 1)">).MongoClient;
</span><span style="color: rgba(0, 0, 255, 1)">var</span> url = "mongodb://localhost:27017/"<span style="color: rgba(0, 0, 0, 1)">;
MongoClient.connect(url, { useNewUrlParser: </span><span style="color: rgba(0, 0, 255, 1)">true</span> }, <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(err, db) {
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (err) <span style="color: rgba(0, 0, 255, 1)">throw</span><span style="color: rgba(0, 0, 0, 1)"> err;
</span><span style="color: rgba(0, 0, 255, 1)">var</span> dbo = db.db("runoob"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> mysort = { type: 1<span style="color: rgba(0, 0, 0, 1)"> };
dbo.collection(</span>"site").find().sort(mysort).toArray(<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(err, result) {
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (err) <span style="color: rgba(0, 0, 255, 1)">throw</span><span style="color: rgba(0, 0, 0, 1)"> err;
console.log(result);
db.close();
});
});</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
</div>
<h3>查询分页</h3>
<p>如果要设置指定的返回条数可以使用 <span class="marked">limit() 方法,该方法只接受一个参数,指定了返回的条数。</span></p>
<div class="example">
<h2 class="example">limit():读取两条数据</h2>
<div class="example_code">
<div class="hl-main">
<div class="cnblogs_code"><img id="code_img_closed_94c950ea-87ba-4ef6-9f9a-36d022e41160" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_94c950ea-87ba-4ef6-9f9a-36d022e41160" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_94c950ea-87ba-4ef6-9f9a-36d022e41160" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> MongoClient = require('mongodb'<span style="color: rgba(0, 0, 0, 1)">).MongoClient;
</span><span style="color: rgba(0, 0, 255, 1)">var</span> url = "mongodb://localhost:27017/"<span style="color: rgba(0, 0, 0, 1)">;
MongoClient.connect(url, { useNewUrlParser: </span><span style="color: rgba(0, 0, 255, 1)">true</span> }, <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(err, db) {
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (err) <span style="color: rgba(0, 0, 255, 1)">throw</span><span style="color: rgba(0, 0, 0, 1)"> err;
</span><span style="color: rgba(0, 0, 255, 1)">var</span> dbo = db.db("runoob"<span style="color: rgba(0, 0, 0, 1)">);
dbo.collection(</span>"site").find().limit(2).toArray(<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(err, result) {
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (err) <span style="color: rgba(0, 0, 255, 1)">throw</span><span style="color: rgba(0, 0, 0, 1)"> err;
console.log(result);
db.close();
});
});</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
</div>
</div>
</div>
<p>如果要指定跳过的条数,可以使用 <span class="marked">skip() 方法。</span></p>
<div class="example">
<h2 class="example">skip(): 跳过前面两条数据,读取两条数据</h2>
<div class="example_code">
<div class="hl-main">
<div class="cnblogs_code"><img id="code_img_closed_58199918-463b-4ac0-a90a-8a9c12555173" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_58199918-463b-4ac0-a90a-8a9c12555173" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_58199918-463b-4ac0-a90a-8a9c12555173" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> MongoClient = require('mongodb'<span style="color: rgba(0, 0, 0, 1)">).MongoClient;
</span><span style="color: rgba(0, 0, 255, 1)">var</span> url = "mongodb://localhost:27017/"<span style="color: rgba(0, 0, 0, 1)">;
MongoClient.connect(url, { useNewUrlParser: </span><span style="color: rgba(0, 0, 255, 1)">true</span> }, <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(err, db) {
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (err) <span style="color: rgba(0, 0, 255, 1)">throw</span><span style="color: rgba(0, 0, 0, 1)"> err;
</span><span style="color: rgba(0, 0, 255, 1)">var</span> dbo = db.db("runoob"<span style="color: rgba(0, 0, 0, 1)">);
dbo.collection(</span>"site").find().skip(2).limit(2).toArray(<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(err, result) {
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (err) <span style="color: rgba(0, 0, 255, 1)">throw</span><span style="color: rgba(0, 0, 0, 1)"> err;
console.log(result);
db.close();
});
});</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
</div>
</div>
</div>
<h3>连接操作</h3>
<p>mongoDB 不是一个关系型数据库,但我们可以使用 <span class="marked">$lookup 来实现左连接。</span></p>
<p>例如我们有两个集合数据分别为:</p>
<p>集合1:orders</p>
<pre class="prettyprint prettyprinted"><span class="pun">[<span class="pln">
<span class="pun">{<span class="pln"> _id<span class="pun">:<span class="pln"> <span class="lit">1<span class="pun">,<span class="pln"> product_id<span class="pun">:<span class="pln"> <span class="lit">154<span class="pun">,<span class="pln"> status<span class="pun">:<span class="pln"> <span class="lit">1<span class="pln"> <span class="pun">}<span class="pln">
<span class="pun">]</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></pre>
<p>集合2:products</p>
<pre class="prettyprint prettyprinted"><span class="pun">[<span class="pln">
<span class="pun">{<span class="pln"> _id<span class="pun">:<span class="pln"> <span class="lit">154<span class="pun">,<span class="pln"> name<span class="pun">:<span class="pln"> <span class="str">'笔记本电脑'<span class="pln"> <span class="pun">},<span class="pln">
<span class="pun">{<span class="pln"> _id<span class="pun">:<span class="pln"> <span class="lit">155<span class="pun">,<span class="pln"> name<span class="pun">:<span class="pln"> <span class="str">'耳机'<span class="pln"> <span class="pun">},<span class="pln">
<span class="pun">{<span class="pln"> _id<span class="pun">:<span class="pln"> <span class="lit">156<span class="pun">,<span class="pln"> name<span class="pun">:<span class="pln"> <span class="str">'台式电脑'<span class="pln"> <span class="pun">}<span class="pln">
<span class="pun">]</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></pre>
<div class="example">
<h2 class="example">$lookup 实现左连接</h2>
<div class="example_code">
<div class="hl-main">
<div class="cnblogs_code"><img id="code_img_closed_d7aa50ce-0914-40e1-b9eb-4dfae0623364" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_d7aa50ce-0914-40e1-b9eb-4dfae0623364" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_d7aa50ce-0914-40e1-b9eb-4dfae0623364" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> MongoClient = require('mongodb'<span style="color: rgba(0, 0, 0, 1)">).MongoClient;
</span><span style="color: rgba(0, 0, 255, 1)">var</span> url = "mongodb://127.0.0.1:27017/"<span style="color: rgba(0, 0, 0, 1)">;
MongoClient.connect(url, { useNewUrlParser: </span><span style="color: rgba(0, 0, 255, 1)">true</span> }, <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(err, db) {
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (err) <span style="color: rgba(0, 0, 255, 1)">throw</span><span style="color: rgba(0, 0, 0, 1)"> err;
</span><span style="color: rgba(0, 0, 255, 1)">var</span> dbo = db.db("runoob"<span style="color: rgba(0, 0, 0, 1)">);
dbo.collection(</span>'orders'<span style="color: rgba(0, 0, 0, 1)">).aggregate([
{ $lookup:
{
from: </span>'products', <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 右集合</span>
localField: 'product_id', <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 左集合 join 字段</span>
foreignField: '_id', <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 右集合 join 字段</span>
as: 'orderdetails' <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 新生成字段(类型array)</span>
<span style="color: rgba(0, 0, 0, 1)"> }
}
]).toArray(</span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(err, res) {
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (err) <span style="color: rgba(0, 0, 255, 1)">throw</span><span style="color: rgba(0, 0, 0, 1)"> err;
console.log(JSON.stringify(res));
db.close();
});
});</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
</div>
</div>
</div>
<h3>删除集合</h3>
<p>我们可以使用 <span class="marked">drop() 方法来删除集合:</span></p>
<div class="example">
<h2 class="example">drop()</h2>
<div class="example_code">
<div class="hl-main">
<div class="cnblogs_code"><img id="code_img_closed_b095adb0-066b-4faa-b27e-f0301156ccce" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_b095adb0-066b-4faa-b27e-f0301156ccce" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_b095adb0-066b-4faa-b27e-f0301156ccce" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> MongoClient = require('mongodb'<span style="color: rgba(0, 0, 0, 1)">).MongoClient;
</span><span style="color: rgba(0, 0, 255, 1)">var</span> url = "mongodb://localhost:27017/"<span style="color: rgba(0, 0, 0, 1)">;
MongoClient.connect(url, { useNewUrlParser: </span><span style="color: rgba(0, 0, 255, 1)">true</span> }, <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(err, db) {
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (err) <span style="color: rgba(0, 0, 255, 1)">throw</span><span style="color: rgba(0, 0, 0, 1)"> err;
</span><span style="color: rgba(0, 0, 255, 1)">var</span> dbo = db.db("runoob"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 删除 test 集合</span>
dbo.collection("test").drop(<span style="color: rgba(0, 0, 255, 1)">function</span>(err, delOK) {<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 执行成功 delOK 返回 true,否则返回 false</span>
<span style="color: rgba(0, 0, 255, 1)">if</span> (err) <span style="color: rgba(0, 0, 255, 1)">throw</span><span style="color: rgba(0, 0, 0, 1)"> err;
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (delOK) console.log("集合已删除"<span style="color: rgba(0, 0, 0, 1)">);
db.close();
});
});</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p> </p>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="MySignature" role="contentinfo">
合群是堕落的开始优秀的开始是孤行<br><br>
来源:https://www.cnblogs.com/biaogejiushibiao/p/11619282.html
頁:
[1]