调试 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(默认值),本地计算机上运行的任何应用程序都将具有不受限制的访问权限。 这是设计使然,允许本地调试器能够方便地附加。

浏览器、WebSockets 和同源策略

在 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 文件中,选择“Debug As... > Node program”,或者
  • 创建一个调试配置,将调试器附加到正在运行的 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); 等待调试器附加。
node inspect script.js生成子进程以在 --inspect 标志下运行用户的脚本; 并使用主进程运行 CLI 调试器。
node inspect --port=xxxx script.js生成子进程以在 --inspect 标志下运行用户的脚本; 并使用主进程运行 CLI 调试器。 监听端口 port(默认:9229)

启用远程调试场景

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

假设您正在远程计算机 remote.example.com 上运行 Node.js,您希望能够对其进行调试。 在该计算机上,您应该启动 Node.js 进程,使 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 端口上监听由已停止维护的 V8 调试协议定义的调试命令,默认情况下为 5858。 任何说这种协议的调试器客户端都可以连接和调试正在运行的进程; 下面列出了几个流行的调试器。

V8 调试协议不再维护或记录。

内置调试器

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

node-inspector

使用 Chrome DevTools 调试您的 Node.js 应用程序,方法是使用一个中间进程,该进程将 Chromium 中使用的 Inspector 协议转换为 Node.js 中使用的 V8 调试器协议。 有关更多信息,请参阅 https://github.com/node-inspector/node-inspector