Node.js服务仅本地可访问 远程触发Python脚本无响应如何解决
解决方案
1. 修正Node.js服务监听配置
你当前的app.listen仅指定了端口,默认会绑定到127.0.0.1,仅允许本地访问,修改为绑定所有网卡地址:
// 将原代码最后一行替换为 app.listen(port, '0.0.0.0', () => console.log('node python script app listening on 0.0.0.0 port ' + port));
2. 补充异常处理与响应逻辑
当前逻辑未处理Python脚本的错误输出、多段输出拼接,以及跨域请求头,远程浏览器跨域访问时会直接拦截响应,完整修正后的index.js代码如下:
const express = require('express'); const { spawn } = require('child_process'); const app = express(); const port = 8811; // 全局添加跨域头,允许所有来源访问 app.use((req, res, next) => { res.header('Access-Control-Allow-Origin', '*'); res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS'); res.header('Access-Control-Allow-Headers', 'Content-Type'); if (req.method === 'OPTIONS') return res.sendStatus(200); next(); }); app.get('/script', (req, res) => { let data1 = ''; // 初始化空字符串拼接多段输出 const pythonOne = spawn('python3', ['script.py']); // 处理标准输出 pythonOne.stdout.on('data', function(data){ data1 += data.toString(); // 拼接所有输出片段,避免只取最后一段 }) // 处理错误输出,避免错误信息丢失导致无返回 pythonOne.stderr.on('data', function(data){ console.error('python error:', data.toString()); data1 += `\n[Error] ${data.toString()}`; }) pythonOne.on('close', (code) => { console.log("code", code) res.send(data1); }) // 超时处理,避免脚本异常挂起导致前端无响应 setTimeout(() => { if (!res.headersSent) { res.status(504).send('script execution timeout'); } }, 30000); // 30秒超时可根据脚本实际运行时间调整 }) app.listen(port, '0.0.0.0', () => console.log('node python script app listening on 0.0.0.0 port ' + port));
3. 修正Nginx配置,补充超时与头信息透传
原Nginx配置缺少超时设置和头信息透传,远程请求容易因为超时被断开,修正后的script.conf配置如下:
upstream backend { server localhost:8811; keepalive 32; } server { listen 8500; server_name script.example.com; location / { client_max_body_size 50M; proxy_set_header X-Real-IP $remote_addr; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_http_version 1.1; proxy_pass http://backend; # 增加超时设置,适配长运行脚本 proxy_connect_timeout 60s; proxy_send_timeout 60s; proxy_read_timeout 60s; } }
修改后执行nginx -s reload重载配置。
4. 检查服务器防火墙与端口开放
确认服务器的8811、8500端口已在防火墙规则中放行:
- 若使用firewalld:
firewall-cmd --add-port=8811/tcp --permanent && firewall-cmd --add-port=8500/tcp --permanent && firewall-cmd --reload - 若使用ufw:
ufw allow 8811/tcp && ufw allow 8500/tcp
完成以上步骤后重启Node.js服务,再从远程设备测试即可正常获取返回结果。
内容的提问来源于stack exchange,提问作者mirekW
相关产品推荐
相关产品推荐

