如何在浏览器端JS中获取Heroku部署的Node/Express服务器端口?
解决Heroku部署后浏览器端请求后端接口的端口问题
核心问题
浏览器端的asr.js无法直接获取Heroku动态分配的端口,硬编码localhost:8000仅能在本地开发时生效,部署后会失效。以下是几种可行的解决思路:
1. 使用相对路径发起请求(最优方案)
不需要硬编码域名和端口,直接用相对路径请求接口。浏览器会自动根据当前页面的域名、端口拼接完整的请求地址,完美适配本地开发和Heroku部署环境。
修改asr.js中的请求代码:
// 原本地代码 // axios.post('http://localhost:8000/transcription') // 修改后 axios.post('/transcription') .then(response => { // 处理返回的令牌 }) .catch(error => { // 处理错误 });
原理:你的前端页面(asr.html)由Express静态托管,和后端接口属于同一域名/端口,浏览器会自动将相对路径补全为当前页面的完整地址(比如Heroku上的https://your-app-name.herokuapp.com/transcription)。
2. 后端将API基础地址注入前端页面
如果需要明确获取完整的API地址,可以在后端渲染asr.html时,将当前的域名+端口注入到页面的全局变量中,供asr.js使用。
步骤1:修改后端返回asr.html的逻辑
在server.js中,替换原静态托管直接返回asr.html的逻辑,改为读取文件并替换占位符:
const fs = require('fs'); const path = require('path'); app.get('/asr', (req, res) => { const htmlPath = path.join(__dirname, 'public/asr.html'); fs.readFile(htmlPath, 'utf8', (err, htmlContent) => { if (err) { return res.status(500).send('Failed to load page'); } // 获取当前请求的完整基础地址(包含域名和端口) const apiBaseUrl = `${req.protocol}://${req.get('host')}`; // 替换页面中的占位符 const renderedHtml = htmlContent.replace('{{API_BASE_URL}}', apiBaseUrl); res.send(renderedHtml); }); });
步骤2:在asr.html中添加全局变量
在asr.html的<head>中添加脚本,定义全局变量:
<head> <!-- 其他标签 --> <script> window.API_BASE_URL = '{{API_BASE_URL}}'; </script> </head> <body> <!-- 页面内容 --> <script src="asr.js"></script> </body>
步骤3:修改asr.js中的请求代码
axios.post(`${window.API_BASE_URL}/transcription`) .then(response => { // 处理返回的令牌 }) .catch(error => { // 处理错误 });
3. 前端构建时注入环境变量(适合使用打包工具的场景)
如果你的前端项目使用Webpack、Vite等打包工具,可以在构建时注入环境变量:
- 本地开发时,设置
VITE_API_BASE_URL=http://localhost:8000 - 部署到Heroku时,设置
VITE_API_BASE_URL=(空值,自动使用相对路径)
然后在asr.js中使用:
axios.post(`${import.meta.env.VITE_API_BASE_URL}/transcription`)
注意:这种方法需要前端项目支持环境变量注入,纯静态文件场景下不如前两种方案直接。
内容的提问来源于stack exchange,提问作者jcomp_03
相关产品推荐
相关产品推荐

