Heroku生产环境Angular+Node.js请求端口配置问题求助
问题描述
我的应用客户端使用Angular,后端采用Node.js,但在Heroku生产环境中无法正确配置。开发环境下,我将Node.js服务器运行在3000端口,Angular客户端所有HTTP请求都发送至http://localhost:3000,运行正常。但当我将Angular客户端文件放在dist目录下与Node.js服务器一同部署到Heroku时,Heroku会随机分配端口,导致所有指向http://localhost:3000的HTTP请求失败。请问如何确定Heroku上的Node端口,或者如何在Angular客户端中获取该端口?
你的现有代码
服务器代码:
let port = normalizePort(process.env.PORT || '3000'); app.set('port', port); const server = http.createServer(app); server.listen(port, () => console.log('app listening on port ' + port)); server.on('error', onError); server.on('listening', onListening);
客户端环境配置:
export const environment = { production: true, serverUrl: 'http://localhost:3000' };
解决方案:用相对路径替代硬编码地址
其实你完全不需要让Angular客户端知道Heroku分配的具体端口号,因为你的前端和后端是部署在同一个Heroku应用实例下的,直接用相对路径发送请求就能自动匹配当前域名和端口,完美解决问题。
步骤1:修改Angular生产环境配置
打开src/environments/environment.prod.ts,把serverUrl改成空字符串:
export const environment = { production: true, serverUrl: '' };
之后在你发送HTTP请求的服务里,比如:
// 示例:用户列表请求 getUsers() { return this.http.get(`${environment.serverUrl}/api/users`); }
生产环境下这段代码会自动变成/api/users,浏览器会用当前页面的域名+端口来发送请求,完全不需要手动指定。
步骤2:配置Node.js后端托管静态文件
确保你的Node.js服务器能正确托管Angular打包后的dist文件,这样前端页面和后端API在同一个域名下,既不会有跨域问题,相对路径也能正确指向后端接口。如果用Express的话,添加以下代码:
const path = require('path'); // 托管Angular静态资源 app.use(express.static(path.join(__dirname, 'dist/你的Angular项目名称'))); // 处理单页应用路由:所有非API请求返回index.html app.get('*', (req, res) => { res.sendFile(path.join(__dirname, 'dist/你的Angular项目名称/index.html')); });
记得把你的Angular项目名称换成你实际的Angular项目名称(也就是dist目录下的子文件夹名)。
为什么这能行?
Heroku会自动把外部请求路由到它分配给你应用的端口上,而你的Node.js代码已经通过process.env.PORT获取并监听了这个端口。前端用相对路径的话,浏览器会自动复用当前页面的域名和端口,完全不需要手动去获取或配置端口号。
开发环境兼容
如果你不想修改开发环境的配置,保持environment.ts里的serverUrl: 'http://localhost:3000'即可——Angular在打包生产版本时会自动使用environment.prod.ts的配置,开发时则用本地的配置,互不影响。
内容的提问来源于stack exchange,提问作者Ron Badur

