如何用Node.js代码获取ngrok的HTTPS地址及重启自动获取?
Absolutely, you can absolutely grab that ngrok HTTPS address programmatically—this is a super common use case for folks using ngrok with Node.js, especially when dealing with server restarts. Let’s break down how to do this step by step:
ngrok comes with a local API that runs on port 4040 by default (you can customize this if needed). This API exposes all active tunnel details, including the public HTTPS URL—no messy log parsing required.
First, start ngrok with your target port (replace XXXX with your Node.js server's listening port):
ngrok http XXXX
Or, if you want ngrok to restart automatically alongside your server, you can spawn it directly from your Node.js code (we’ll cover that next).
Here’s a practical example using Node.js’s native fetch API (swap in axios if that’s your preference) to pull the tunnel info, save it, and send notifications:
const fetch = require('node-fetch'); const fs = require('fs'); async function getNgrokHttpsUrl() { try { // Hit ngrok's local API endpoint const response = await fetch('http://localhost:4040/api/tunnels'); const tunnelData = await response.json(); // Filter for the HTTPS tunnel (ignore HTTP if you don't need it) const httpsTunnel = tunnelData.tunnels.find(tunnel => tunnel.proto === 'https'); if (httpsTunnel) { const publicHttpsUrl = httpsTunnel.public_url; console.log(`Successfully retrieved ngrok HTTPS address: ${publicHttpsUrl}`); // Save the address for later use (e.g., to a local file) fs.writeFileSync('./ngrok-active-url.txt', publicHttpsUrl); // Send your "Back Home" notification (customize this to your needs) sendBackHomeNotification(publicHttpsUrl); return publicHttpsUrl; } else { console.error('No HTTPS tunnel found—double-check ngrok is running and connected.'); return null; } } catch (error) { console.error('Failed to fetch ngrok tunnel details:', error.message); return null; } } // Example notification function—replace with your actual logic (email, Slack, etc.) function sendBackHomeNotification(url) { console.log(`📤 Sending notification to "Back Home": New ngrok address is ${url}`); // For email, you could use `nodemailer` (install via npm install nodemailer) here } // Call this function when your server finishes starting up getNgrokHttpsUrl();
To make sure ngrok spins back up whenever your server restarts, you have two solid options:
Option 1: Spawn ngrok directly from Node.js
Use the child_process module to launch ngrok programmatically—this way, it starts and stops with your server:
const { spawn } = require('child_process'); const SERVER_PORT = XXXX; // Replace with your actual port function startNgrok() { // Spawn the ngrok process const ngrokProcess = spawn('ngrok', ['http', SERVER_PORT]); // Optional: Log ngrok output for debugging ngrokProcess.stdout.on('data', (data) => { console.log(`ngrok logs: ${data}`); }); ngrokProcess.stderr.on('data', (data) => { console.error(`ngrok errors: ${data}`); }); // Wait 2-3 seconds for ngrok to establish the tunnel before fetching the URL setTimeout(getNgrokHttpsUrl, 3000); } // Call this when your server is ready to accept connections startNgrok();
Note: Ensure ngrok is in your system PATH, or provide the full path to the executable (e.g., ./ngrok if it’s in your project folder).
Option 2: Use a process manager like PM2
PM2 can manage both your Node.js server and ngrok as persistent processes, restarting them if they crash. Create an ecosystem.config.js file:
module.exports = { apps: [ { name: 'my-node-server', script: 'server.js', env: { NODE_ENV: 'production', PORT: XXXX } }, { name: 'ngrok-tunnel', script: 'ngrok', args: 'http XXXX', autorestart: true, watch: false } ] };
Start both processes with pm2 start ecosystem.config.js.
- Wait for ngrok to initialize: Don’t call the API immediately after starting ngrok—give it 2-3 seconds to establish the tunnel (the
setTimeoutin the example handles this). - API port conflicts: If port 4040 is in use, start ngrok with a custom API port:
ngrok http XXXX --api=4041, then update your fetch URL tohttp://localhost:4041/api/tunnels. - Free ngrok limits: Free tunnels expire after 8 hours, so you’ll need to add logic to re-fetch the URL if your server runs longer than that.
内容的提问来源于stack exchange,提问作者mrSidX

