调试 Node.js

¥Debugging Node.js

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

¥This guide will help you get started debugging your Node.js apps and scripts.

启用检查器

¥Enable Inspector

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

¥When started with the --inspect switch, a Node.js process listens for a debugging client. By default, it will listen at host and port 127.0.0.1:9229. Each process is also assigned a unique UUID.

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

¥Inspector clients must know and specify host address, port, and UUID to connect. A full URL will look something like ws://127.0.0.1:9229/0f2c936f-b1cd-4ac9-aab3-f63b0f33d55e.

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

¥Node.js will also start listening for debugging messages if it receives a SIGUSR1 signal. (SIGUSR1 is not available on Windows.) In Node.js 7 and earlier, this activates the legacy Debugger API. In Node.js 8 and later, it will activate the Inspector API.

安全影响

¥Security Implications

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

¥Since the debugger has full access to the Node.js execution environment, a malicious actor able to connect to this port may be able to execute arbitrary code on behalf of the Node.js process. It is important to understand the security implications of exposing the debugger port on public and private networks.

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

¥Exposing the debug port publicly is unsafe

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

¥If the debugger is bound to a public IP address, or to 0.0.0.0, any clients that can reach your IP address will be able to connect to the debugger without any restriction and will be able to run arbitrary code.

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

¥By default node --inspect binds to 127.0.0.1. You explicitly need to provide a public IP address or 0.0.0.0, etc., if you intend to allow external connections to the debugger. Doing so may expose you to a potentially significant security threat. We suggest you ensure appropriate firewalls and access controls in place to prevent a security exposure.

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

¥See the section on 'Enabling remote debugging scenarios' on some advice on how to safely allow remote debugger clients to connect.

本地应用可以完全访问检查器

¥Local applications have full access to the inspector

即使你将检查器端口绑定到 127.0.0.1(默认值),你机器上本地运行的任何应用都将具有不受限制的访问权限。这是设计使本地调试器能够方便地连接。

¥Even if you bind the inspector port to 127.0.0.1 (the default), any applications running locally on your machine will have unrestricted access. This is by design to allow local debuggers to be able to attach conveniently.

浏览器、WebSocket 和同源策略

¥Browsers, WebSockets and same-origin policy

在 Web 浏览器中打开的网站可以在浏览器安全模型下触发 WebSocket 和 HTTP 请求。需要初始 HTTP 连接才能获得唯一的调试器会话 ID。同源策略阻止网站建立此 HTTP 连接。为了针对 DNS 重新绑定攻击 提供额外的安全性,Node.js 会验证连接的 '主机' 标头是否指定了 IP 地址或精确指定了 localhost

¥Websites open in a web-browser can make WebSocket and HTTP requests under the browser security model. An initial HTTP connection is necessary to obtain a unique debugger session id. The same-origin-policy prevents websites from being able to make this HTTP connection. For additional security against DNS rebinding attacks, Node.js verifies that the 'Host' headers for the connection either specify an IP address or localhost precisely.

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

¥These security policies disallow connecting to a remote debug server by specifying the hostname. You can work-around this restriction by specifying either the IP address or by using ssh tunnels as described below.

检查器客户端

¥Inspector Clients

node inspect myscript.js 提供了一个最小的 CLI 调试器。几个商业和开源工具也可以连接到 Node.js 检查器。

¥A minimal CLI debugger is available with node inspect myscript.js. Several commercial and open source tools can also connect to the Node.js Inspector.

Chrome DevTools 55+、Microsoft Edge

  • 选项 1:在基于 Chromium 的浏览器中打开 chrome://inspect,或在 Edge 中打开 edge://inspect。单击配置按钮并确保列出了你的目标主机和端口。

    ¥Option 1: Open chrome://inspect in a Chromium-based browser or edge://inspect in Edge. Click the Configure button and ensure your target host and port are listed.

  • 选项 2:从 /json/list 的输出中复制 devtoolsFrontendUrl(参见上文)或 --inspect 提示文本并粘贴到 Chrome 中。

    ¥Option 2: Copy the devtoolsFrontendUrl from the output of /json/list (see above) or the --inspect hint text and paste into Chrome.

有关更多信息,请参阅 https://github.com/ChromeDevTools/devtools-frontendhttps://www.microsoftedgeinsider.com

¥See https://github.com/ChromeDevTools/devtools-frontend, https://www.microsoftedgeinsider.com for more information.

Visual Studio Code 1.10+

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

    ¥In the Debug panel, click the settings icon to open .vscode/launch.json. Select "Node.js" for initial setup.

有关更多信息,请参阅 https://github.com/microsoft/vscode

¥See https://github.com/microsoft/vscode for more information.

Visual Studio 2017+

JetBrains WebStorm 和其他 JetBrains IDE

¥JetBrains WebStorm and other JetBrains IDEs

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

    ¥Create a new Node.js debug configuration and hit Debug. --inspect will be used by default for Node.js 7+. To disable uncheck js.debugger.node.use.inspect in the IDE Registry. To learn more about running and debugging Node.js in WebStorm and other JetBrains IDEs, check out WebStorm online help.

chrome-remote-interface

有关更多信息,请参阅 https://github.com/cyrus-and/chrome-remote-interface

¥See https://github.com/cyrus-and/chrome-remote-interface for more information.

Gitpod

有关更多信息,请参阅 https://www.gitpod.io

¥See https://www.gitpod.io for more information.

带有 Eclipse Wild Web Developer 扩展的 Eclipse IDE

¥Eclipse IDE with Eclipse Wild Web Developer extension

  • 从 .js 文件中,选择“Debug As...Node 程序”,或

    ¥From a .js file, choose "Debug As... > Node program", or

  • 创建调试配置以将调试器附加到正在运行的 Node.js 应用(已使用 --inspect 启动)。

    ¥Create a Debug Configuration to attach debugger to running Node.js application (already started with --inspect).

有关更多信息,请参阅 https://eclipse.org/eclipseide

¥See https://eclipse.org/eclipseide for more information.

命令行选项

¥Command-line options

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

¥The following table lists the impact of various runtime flags on debugging:

标志含义
--inspect启用检查器代理;监听默认地址和端口 (127.0.0.1:9229)
--inspect=[host:port]启用检查器代理;绑定到地址或主机名主机(默认值:127.0.0.1);监听端口 port (默认值:9229)
--inspect-brk启用检查器代理;监听默认地址和端口 (127.0.0.1:9229);在用户代码启动前中断
--inspect-brk=[host:port]启用检查器代理;绑定到地址或主机名主机(默认值:127.0.0.1);监听端口 port (默认值:9229);在用户代码启动前中断
--inspect-wait启用检查器代理;监听默认地址和端口 (127.0.0.1:9229);等待调试器附加。
--inspect-wait=[host:port]启用检查器代理;绑定到地址或主机名主机(默认值:127.0.0.1);监听端口 port (默认值:9229);等待调试器附加。
node inspect script.js生成子进程以在 --inspect 标志下运行用户的脚本;并使用主进程运行 CLI 调试器。
node inspect --port=xxxx script.js生成子进程以在 --inspect 标志下运行用户的脚本;并使用主进程运行 CLI 调试器。监听端口 port (默认值:9229)

启用远程调试场景

¥Enabling remote debugging scenarios

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

¥We recommend that you never have the debugger listen on a public IP address. If you need to allow remote debugging connections we recommend the use of ssh tunnels instead. We provide the following example for illustrative purposes only. Please understand the security risk of allowing remote access to a privileged service before proceeding.

假设你正在远程计算机 remote.example.com 上运行 Node.js,你希望能够对其进行调试。在该机器上,你应该启动 node 进程,检查器仅监听本地主机(默认)。

¥Let's say you are running Node.js on a remote machine, remote.example.com, that you want to be able to debug. On that machine, you should start the node process with the inspector listening only to localhost (the default).

node --inspect server.js

现在,在你想要启动调试客户端连接的本地机器上,你可以设置一个 ssh 隧道:

¥Now, on your local machine from where you want to initiate a debug client connection, you can setup an ssh tunnel:

ssh -L 9221:localhost:9229 user@remote.example.com

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

¥This starts a ssh tunnel session where a connection to port 9221 on your local machine will be forwarded to port 9229 on remote.example.com. You can now attach a debugger such as Chrome DevTools or Visual Studio Code to localhost:9221, which should be able to debug as if the Node.js application was running locally.

旧版调试器

¥Legacy Debugger

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

¥The legacy debugger has been deprecated as of Node.js 7.7.0. Please use --inspect and Inspector instead.

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

¥When started with the --debug or --debug-brk switches in version 7 and earlier, Node.js listens for debugging commands defined by the discontinued V8 Debugging Protocol on a TCP port, by default 5858. Any debugger client which speaks this protocol can connect to and debug the running process; a couple popular ones are listed below.

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

¥The V8 Debugging Protocol is no longer maintained or documented.

内置调试器

¥Built-in Debugger

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

¥Start node debug script_name.js to start your script under the builtin command-line debugger. Your script starts in another Node.js process started with the --debug-brk option, and the initial Node.js process runs the _debugger.js script and connects to your target. See docs for more information.

node-inspector

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

¥Debug your Node.js app with Chrome DevTools by using an intermediary process which translates the Inspector Protocol used in Chromium to the V8 Debugger protocol used in Node.js. See https://github.com/node-inspector/node-inspector for more information.