部署在Heroku等远程主机时请求报503错误排查求助
Node.js 服务器用 https.get 发请求返回503,本地正常的排查方案
核心原因分析(结合CloudFlare特性)
你的问题大概率是CloudFlare的安全机制拦截了服务器请求,本地请求正常是因为两者的请求特征、环境存在差异:
- 请求头过于简陋:Node.js的
https.get默认不带完整的浏览器请求头(比如User-Agent、Accept系列字段),CloudFlare会把这种请求判定为爬虫或恶意请求,触发503拦截(尤其是该站点需要安全审核的情况下)。 - 服务器IP被拉黑:云服务器的共享IP段经常被用于批量爬虫,很可能已经进入CloudFlare的IP黑名单,直接被拦截;而本地家庭/办公IP不在黑名单里,所以能正常访问。
- 无法处理人机验证:本地浏览器会自动加载CloudFlare的JS验证脚本,完成隐形验证;但
https.get是纯HTTP请求,无法执行JS,过不了验证就返回503。 - 请求速率超限:服务器可能短时间内发了太多请求,触发CloudFlare的速率限制,本地请求频率低,没触发阈值。
针对性解决方法
1. 补全浏览器级别的请求头
模拟真实浏览器的请求头,至少补上User-Agent、Accept、Accept-Language,示例代码:
const https = require('https'); const options = { hostname: 'shahed4u.vip', path: '/目标路径', method: 'GET', headers: { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8', 'Accept-Language': 'zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3' } }; const req = https.get(options, (res) => { res.on('data', (chunk) => { console.log(chunk.toString()); }); }); req.on('error', (e) => { console.error(`请求出错: ${e.message}`); });
2. 检查并更换服务器IP
- 先确认服务器IP是否在CloudFlare的黑名单里:可以用其他工具测试该IP访问目标站点的情况;
- 如果是云服务器,联系服务商申请更换独立IP,或者使用代理IP来发送请求。
3. 用无头浏览器处理人机验证
如果CloudFlare要求JS验证,https.get根本绕不过,得用puppeteer这类无头浏览器工具模拟真实浏览器行为,自动完成验证:
const puppeteer = require('puppeteer'); (async () => { const browser = await puppeteer.launch({ headless: 'new' }); const page = await browser.newPage(); await page.setUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36'); await page.goto('https://shahed4u.vip/目标路径', { waitUntil: 'networkidle2' }); const pageContent = await page.content(); console.log(pageContent); await browser.close(); })();
4. 控制请求速率
给请求添加随机延迟,避免短时间内发送大量请求触发限流:
function sendRequestWithDelay() { const delay = Math.floor(Math.random() * 2000) + 1000; setTimeout(() => { // 放入之前的https.get请求代码 console.log('发送请求...'); }, delay); } // 批量请求示例 for (let i = 0; i < 5; i++) { sendRequestWithDelay(); }
5. 完全对齐本地请求参数
用抓包工具(比如Charles、Fiddler)对比本地请求和服务器请求的所有细节:包括Cookie、请求头、URL参数等,确保服务器请求和本地请求完全一致。如果本地请求有登录后的Cookie,服务器请求也要带上对应的Cookie字段。
内容的提问来源于stack exchange,提问作者Bellator
相关产品推荐
相关产品推荐

