调试 Node.js

本指南将帮助你开始调试你的 Node.js 应用和脚本。

启用 Inspector

当使用 --inspect 开关启动时,Node.js 进程会监听调试客户端。默认情况下,它会监听主机和端口 127.0.0.1:9229。每个进程也会被分配一个唯一的 UUID

Inspector 客户端必须知道并指定主机地址、端口和 UUID 才能连接。一个完整的 URL 看起来会像这样 ws://127.0.0.1:9229/0f2c936f-b1cd-4ac9-aab3-f63b0f33d55e

如果 Node.js 收到一个 SIGUSR1 信号,它也会开始监听调试消息。(SIGUSR1 在 Windows 上不可用。)在 Node.js 7 及更早版本中,这会激活旧版的调试器 API。在 Node.js 8 及更高版本中,它会激活 Inspector API。

安全影响

由于调试器可以完全访问 Node.js 执行环境,能够连接到此端口的恶意行为者可能能够代表 Node.js 进程执行任意代码。了解在公共和私有网络上暴露调试器端口的安全影响非常重要。

公开暴露调试端口是不安全的

如果调试器绑定到公共 IP 地址或 0.0.0.0,任何能够访问您 IP 地址的客户端都将能够无限制地连接到调试器,并能够运行任意代码。

默认情况下,node --inspect 绑定到 127.0.0.1。如果您打算允许外部连接到调试器,您需要明确提供一个公共 IP 地址或 0.0.0.0 等。这样做可能会使您面临潜在的重大安全威胁。我们建议您确保有适当的防火墙和访问控制措施,以防止安全暴露。

请参阅“启用远程调试场景”部分,了解如何安全地允许远程调试器客户端连接的一些建议。

本地应用程序可以完全访问 inspector

即使您将 inspector 端口绑定到 127.0.0.1(默认),在您的机器上本地运行的任何应用程序都将拥有无限制的访问权限。这是为了方便本地调试器能够轻松地附加而设计的。

浏览器、WebSocket 和同源策略

在 Web 浏览器中打开的网站可以在浏览器安全模型下发出 WebSocket 和 HTTP 请求。需要进行初始 HTTP 连接以获取唯一的调试器会话 ID。同源策略阻止网站进行此 HTTP 连接。为了增加对DNS 重绑定攻击的安全性,Node.js 会验证连接的“Host”头是否精确指定了 IP 地址或 localhost

这些安全策略不允许通过指定主机名连接到远程调试服务器。您可以通过指定 IP 地址或使用 ssh 隧道(如下所述)来绕过此限制。

Inspector 客户端

一个最小的 CLI 调试器可通过 node inspect myscript.js 使用。一些商业和开源工具也可以连接到 Node.js Inspector。

Chrome DevTools 55+、Microsoft Edge

  • 选项 1:在基于 Chromium 的浏览器中打开 chrome://inspect 或在 Edge 中打开 edge://inspect。点击“配置”按钮,并确保您的目标主机和端口已列出。
  • 选项 2:从 /json/list 的输出(见上文)或 --inspect 提示文本中复制 devtoolsFrontendUrl,并粘贴到 Chrome 中。

更多信息请参见 https://github.com/ChromeDevTools/devtools-frontendhttps://www.microsoftedgeinsider.com

Visual Studio Code 1.10+

  • 在“调试”面板中,单击设置图标以打开 .vscode/launch.json。选择“Node.js”进行初始设置。

更多信息请参见 https://github.com/microsoft/vscode

Visual Studio 2017+

  • 从菜单中选择“调试 > 开始调试”或按 F5。
  • 详细说明.

JetBrains WebStorm 和其他 JetBrains IDE

  • 创建一个新的 Node.js 调试配置并点击“调试”。对于 Node.js 7+,默认会使用 --inspect。要禁用,请在 IDE 注册表中取消选中 js.debugger.node.use.inspect。要了解更多关于在 WebStorm 和其他 JetBrains IDE 中运行和调试 Node.js 的信息,请查看 WebStorm 在线帮助

chrome-remote-interface

更多信息请参见 https://github.com/cyrus-and/chrome-remote-interface

Gitpod

  • Debug 视图启动一个 Node.js 调试配置或按 F5详细说明

更多信息请参见 https://www.gitpod.io

带有 Eclipse Wild Web Developer 扩展的 Eclipse IDE

  • 从 .js 文件中,选择“调试方式... > Node 程序”,或者
  • 创建一个调试配置以将调试器附加到正在运行的 Node.js 应用程序(已使用 --inspect 启动)。

更多信息请参见 https://eclipse.org/eclipseide

命令行选项

下表列出了各种运行时标志对调试的影响

标志含义
--inspect启用 inspector 代理;在默认地址和端口(127.0.0.1:9229)上监听
--inspect=[host:port]启用 inspector 代理;绑定到地址或主机名 host(默认:127.0.0.1);在端口 port 上监听(默认:9229)
--inspect-brk启用 inspector 代理;在默认地址和端口(127.0.0.1:9229)上监听;在用户代码开始前中断
--inspect-brk=[host:port]启用 inspector 代理;绑定到地址或主机名 host(默认:127.0.0.1);在端口 port 上监听(默认:9229);在用户代码开始前中断
--inspect-wait启用 inspector 代理;在默认地址和端口(127.0.0.1:9229)上监听;等待调试器附加。
--inspect-wait=[host:port]启用 inspector 代理;绑定到地址或主机名 host(默认:127.0.0.1);在端口 port 上监听(默认:9229);等待调试器附加。
--disable-sigusr1禁用通过向进程发送 SIGUSR1 信号来启动调试会话的能力。
node inspect script.js生成子进程以在 --inspect 标志下运行用户脚本;并使用主进程运行 CLI 调试器。
node inspect --port=xxxx script.js生成子进程以在 --inspect 标志下运行用户脚本;并使用主进程运行 CLI 调试器。在端口 port 上监听(默认:9229)

启用远程调试场景

我们建议您永远不要让调试器在公共 IP 地址上监听。如果您需要允许远程调试连接,我们建议使用 ssh 隧道。我们提供以下示例仅用于说明目的。在继续之前,请了解允许远程访问特权服务的安全风险。

假设您正在远程机器 remote.example.com 上运行 Node.js,并且您希望能够进行调试。在该机器上,您应该启动 node 进程,让 inspector 仅监听 localhost(默认)。

node --inspect server.js

现在,在您想要发起调试客户端连接的本地机器上,您可以设置一个 ssh 隧道

ssh -L 9221:localhost:9229 [email protected]

这将启动一个 ssh 隧道会话,其中到您本地机器上端口 9221 的连接将被转发到 remote.example.com 上的端口 9229。您现在可以将调试器(如 Chrome DevTools 或 Visual Studio Code)附加到 localhost:9221,它应该能够像 Node.js 应用程序在本地运行一样进行调试。

旧版调试器

自 Node.js 7.7.0 起,旧版调试器已被弃用。请改用 --inspect 和 Inspector。

当在版本 7 及更早版本中使用 --debug--debug-brk 开关启动时,Node.js 会在一个 TCP 端口(默认为 5858)上监听由已停用的 V8 调试协议定义的调试命令。任何支持此协议的调试器客户端都可以连接并调试正在运行的进程;下面列出了一些流行的客户端。

V8 调试协议已不再维护或提供文档。

内置调试器

启动 node debug script_name.js 以在内置的命令行调试器下启动您的脚本。您的脚本在另一个以 --debug-brk 选项启动的 Node.js 进程中开始,而初始的 Node.js 进程运行 _debugger.js 脚本并连接到您的目标。更多信息请参见文档

node-inspector

通过使用一个中间进程,将 Chromium 中使用的 Inspector 协议转换为 Node.js 中使用的 V8 调试器协议,来使用 Chrome DevTools 调试您的 Node.js 应用。更多信息请参见 https://github.com/node-inspector/node-inspector