调试 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.
检查器客户端必须知道并指定主机地址、端口和 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.
如果 Node.js 收到 SIGUSR1 信号,它也会开始监听调试消息。(SIGUSR1 在 Windows 上不可用。)在 Node.js 7 及更早版本中,这会启用传统的调试器 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 are 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.
浏览器、WebSockets 与同源策略
🌐 Browsers, WebSockets and same-origin policy
在网络浏览器中打开的网站可以根据浏览器的安全模型发起 WebSocket 和 HTTP 请求。需要初始的 HTTP 连接来获取唯一的调试器会话 ID。同源策略会阻止网站进行此 HTTP 连接。为了防止 DNS 重新绑定攻击,Node.js 会验证连接的 'Host' 头部是否准确地指定了一个 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 来使用最简洁的命令行调试器。还有许多商业和开源工具也可以连接到 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 开发者工具 55,Microsoft Edge
🌐 Chrome DevTools 55+, Microsoft Edge
选项 1:使用内置的 DevTools 界面
🌐 Option 1: Use the built-in DevTools UI
- 在你的浏览器中打开
chrome://inspect(在 Microsoft Edge 中为edge://inspect)。 - 点击“配置”按钮,确保列出了你的目标主机和端口。
- 你的 Node.js 应用应该出现在远程目标列表中。
选项 2:手动连接
🌐 Option 2: Connect manually
- 访问
http://localhost:<inspect-port>/json/list。它应该返回一个包含devtoolsFrontendUrl的 JSON 对象。 - 从响应中复制
devtoolsFrontendUrl的值,并将其粘贴到浏览器的地址栏中。
有关更多信息,请参见 Chrome 开发者工具前端 和 Microsoft Edge 开发者工具指南。
🌐 See Chrome DevTools Frontend and Microsoft Edge DevTools Guide for more information.
Visual Studio 代码 1.10
🌐 Visual Studio Code 1.10+
- 在调试面板中,点击设置图标以打开
.vscode/launch.json。初始设置时选择“Node.js”。
有关更多信息,请参见 https://code.visualstudio.com/docs/nodejs/nodejs-debugging。
🌐 See https://code.visualstudio.com/docs/nodejs/nodejs-debugging for more information.
Visual Studio 2017
🌐 Visual Studio 2017+
- 从菜单中选择“调试 > 开始调试”或按 F5。
- 详细说明。
JetBrains WebStorm 及其他 JetBrains IDE
🌐 JetBrains WebStorm and other JetBrains IDEs
- 创建一个新的 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。
🌐 See https://github.com/cyrus-and/chrome-remote-interface for more information.
搭配 Eclipse Wild Web Developer 扩展的 Eclipse IDE
🌐 Eclipse IDE with Eclipse Wild Web Developer extension
- 在 .js 文件中,选择 “调试方式... > Node 程序”,或者
- 创建调试配置以将调试器附加到正在运行的 Node.js 应用(已使用
--inspect启动)。
请访问 https://eclipseide.org/ 获取更多信息。
🌐 See https://eclipseide.org/ for more information.
命令行选项
🌐 Command-line options
下表列出了各种运行时标志对调试的影响:
🌐 The following table lists the impact of various runtime flags on debugging:
| Flag | Meaning |
|---|---|
| --inspect | Enable inspector agent; Listen on default address and port (127.0.0.1:9229) |
| --inspect=[host:port] | Enable inspector agent; Bind to address or hostname host (default: 127.0.0.1); Listen on port port (default: 9229) |
| --inspect-brk | Enable inspector agent; Listen on default address and port (127.0.0.1:9229); Break before user code starts |
| --inspect-brk=[host:port] | Enable inspector agent; Bind to address or hostname host (default: 127.0.0.1); Listen on port port (default: 9229); Break before user code starts |
| --inspect-wait | Enable inspector agent; Listen on default address and port (127.0.0.1:9229); Wait for debugger to be attached. |
| --inspect-wait=[host:port] | Enable inspector agent; Bind to address or hostname host (default: 127.0.0.1); Listen on port port (default: 9229); Wait for debugger to be attached. |
| --disable-sigusr1 | Disable the ability of starting a debugging session by sending a SIGUSR1 signal to the process. |
| node inspect script.js | Spawn child process to run user's script under --inspect flag; and use main process to run CLI debugger. |
| node inspect --port=xxxx script.js | Spawn child process to run user's script under --inspect flag; and use main process to run CLI debugger. Listen on port port (default: 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 开发者工具或 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。
在版本 7 及更早版本中,如果使用 --debug 或 --debug-brk 参数启动,Node.js 会在 TCP 端口(默认 5858)上监听已废弃的 V8 调试协议定义的调试命令。任何支持该协议的调试器客户端都可以连接并调试正在运行的进程;下面列出了一些流行的选项。
🌐 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 脚本并连接到你的目标进程。更多信息请参见 文档。
🌐 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 检查器
🌐 node-inspector
通过使用一个中间进程来调试你的 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.