入门指南
安装Node之后,让我们尝试构建我们的第一个Web服务器,创建名为“app.js”的文件,并粘贴以下代码:
const http = require('http');
const hostname = '127.0.0.1';
const port = 3000;
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end('Hello World\n');
});
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
之后,使用node app.js
运行你的Web服务器,访问http://localhost:3000,你将看到一条消息'Hello World'
。
调试指南
本指南将帮助你入门调试Node.js应用程序和脚本。
启用Inspector
当使用--inspect
开关启动时,Node.js进程通过WebSockets监听Inspector Protocol定义的诊断命令,默认情况下主机和端口127.0.0.1:9229
,还为每个进程分配了唯一的UUID(例如,0f2c936f-b1cd-4ac9-aab3-f63b0f33d55e
)。
Inspector客户端必须知道并指定要连接到WebSocket接口的主机地址、端口和UUID,完整的URL是ws://127.0.0.1:9229/0f2c936f-b1cd-4ac9-aab3-f63b0f33d55e
,当然取决于实际的主机和端口以及实例的正确UUID。
Inspector还包括一个HTTP端点,用于提供有关调试对象的元数据,包括其WebSocket URL,UUID和Chrome DevTools URL,通过向http://[host:port]/json/list
发送HTTP请求来获取此元数据,这将返回一个JSON对象,如下所示;使用webSocketDebuggerUrl
属性作为URL直接连接到Inspector。
{
"description": "node.js instance",
"devtoolsFrontendUrl": "chrome-devtools://devtools/bundled/inspector.html?experiments=true&v8only=true&ws=127.0.0.1:9229/0f2c936f-b1cd-4ac9-aab3-f63b0f33d55e",
"faviconUrl": "https://nodejs.org/static/favicon.ico",
"id": "0f2c936f-b1cd-4ac9-aab3-f63b0f33d55e",
"title": "node",
"type": "node",
"url": "file://",
"webSocketDebuggerUrl": "ws://127.0.0.1:9229/0f2c936f-b1cd-4ac9-aab3-f63b0f33d55e"
}
在没有--inspect
的情况下启动的Node.js进程也可以通过SIGUSR1
(在Linux和OS X上)发出信号来指示开始侦听调试消息,从Node 7开始,这将激活旧版Debugger API,在Node 8及更高版本中,它将激活Inspector API。
安全影响
由于调试器具有对Node.js执行环境的完全访问权限,因此能够连接到此端口的恶意行为者可以代表Node进程执行任意代码,了解在公共和专用网络上公开调试器端口的安全隐患非常重要。
公开公共调试端口是不安全的
如果调试器绑定到公共IP地址或0.0.0.0
,则任何可以访问你的IP地址的客户端都可以无限制地连接到调试器,并且能够运行任意代码。
默认情况下,node --inspect
绑定到127.0.0.1
,如果你打算允许外部连接到调试器,你需要明确提供公共IP地址或0.0.0.0
等。这样做可能会给你带来潜在的重大安全威胁,我们建议你确保适当的防火墙和访问控制措施,以防止安全风险。
有关如何安全地允许远程调试器客户端连接的一些建议,请参阅“启用远程调试方案”一节。
本地应用程序可以完全访问inspector
即使将inspector端口绑定到127.0.0.1
(默认值),计算机上本地运行的任何应用程序也将具有不受限制的访问权限,这是为了让本地调试器能够方便地连接。
浏览器、WebSockets和同源策略
在Web浏览器中打开的网站可以在浏览器安全模型下进行WebSocket和HTTP请求,需要初始HTTP连接才能获得唯一的调试器会话ID,同源策略阻止网站建立此HTTP连接,为了防止DNS重新绑定攻击的其他安全性,Node.js会验证连接的“主机”标头是否精确指定了IP地址或localhost
或localhost6
。
这些安全策略不允许通过指定主机名来连接到远程调试服务器,你可以通过指定IP地址或使用ssh隧道来解决此限制,如下所述。
Inspector客户端
一些商业和开源工具可以连接到Node的Inspector,这些基本信息如下:
- Node.js Foundation支持的CLI调试器,它使用Inspector协议。
- 一个与Node捆绑在一起的版本,可以与
node inspect myscript.js
一起使用。 - 最新版本也可以独立安装(例如
npm install -g node-inspect
),并与node-inspect myscript.js
一起使用。
Chrome DevTools 55+
- 选项1:在基于Chromium的浏览器中打开
chrome://inspect
,点击配置按钮,确保列出目标主机和端口。 - 选项2:从
/json/list
的输出(见上文)或--inspect
提示文本复制devtoolsFrontendUrl
并粘贴到Chrome中。 - 选项3:安装Chrome扩展程序NIM(Node Inspector Manager):https://chrome.google.com/webstore/detail/nim-node-inspector-manage/gnhhdgbaldcilmgcpfddgdbkhjohddkj。
Visual Studio Code 1.10+
- 在Debug面板中,点击设置图标以打开
.vscode/launch.json
,选择“Node.js”进行初始设置。
Visual Studio 2017
- 从菜单中选择“Debug> Start Debugging”或按
F5
。 - 详细说明。
JetBrains WebStorm 2017.1+和其他JetBrains IDE
- 创建一个新的Node.js调试配置并点击Debug,对于Node.js 7+,默认情况下将使用
--inspect
,要禁用,请在IDE Registry中取消选中js.debugger.node.use.inspect
。
- 用于简化与Inspector Protocol端点的连接的库。
命令行选项
下表列出了各种运行时标志对调试的影响:
--inspect
- 启用inspector代理
- 监听默认地址和端口(127.0.0.1:9229)
--inspect=[host:port]
- 启用inspector代理
- 绑定到地址或主机名,
host
(默认值:127.0.0.1) - 监听端口,
port
(127.0.0.1:9229)
--inspect-brk
- 启用inspector代理
- 监听默认地址和端口(127.0.0.1:9229)
- 在用户代码启动前中断
--inspect-brk=[host:port]
- 启用inspector代理
- 绑定到地址或主机名,
host
(默认值:127.0.0.1) - 监听端口,
port
(127.0.0.1:9229) - 在用户代码启动前中断
node inspect script.js
- 生成子进程以在
--inspect
标志下运行用户脚本,并使用main进程运行CLI调试器。
node inspect --port=xxxx script.js
- 生成子进程以在
--inspect
标志下运行用户脚本,并使用main进程运行CLI调试器。 - 监听端口,
port
(127.0.0.1:9229)
启用远程调试方案
我们建议你永远不要让调试器在公共IP地址上监听,如果你需要允许远程调试连接,我们建议使用ssh隧道,我们提供以下示例仅用于说明目的,请在继续操作之前了解允许远程访问特权服务的安全风险。
假设你在远程计算机remote.example.com
上运行Node,你希望能够进行调试,在该计算机上,你应该启动node进程,并且inspector仅侦听localhost
(默认值)。
$ node --inspect server.js
现在,在要从中启动调试客户端连接的本地计算机上,可以设置ssh隧道:
$ ssh -L 9221:localhost:9229 user@remote.example.com
这将启动ssh
隧道会话,其中与本地计算机上的端口9221
的连接将转发到remote.example.com
上的端口9229
,你现在可以将调试器(如Chrome DevTools或Visual Studio Code)附加到localhost:9221
,它应该能够调试,就好像Node.js应用程序在本地运行一样。
遗留调试器
从Node 7.7.0开始,遗留调试器已被弃用,请改用--inspect
和Inspector。
在版本7及更早版本中使用--debug
或--debug-brk
开关启动时,Node.js将侦听TCP端口上已停用的V8调试协议定义的调试命令,默认情况下为5858
,任何使用这个协议的调试器客户端都可以连接并调试正在运行的进程;下面列出了几个受欢迎的。
不再维护或记录V8调试协议。
- 启动
node debug script_name.js
以在Node的内置命令行调试器下启动脚本,你的脚本在另一个使用--debug-brk
选项启动的Node进程中启动,初始Node进程运行_debugger.js
脚本并连接到你的目标。
- 使用Chrome DevTools调试Node.js应用程序,使用中间进程将Chromium中使用的Inspector协议转换为Node.js中使用的V8 Debugger协议。