前言
使用 Node.js 和 curl 访问同一个 URL,结果却不一样,初步判断是由于请求头不一样导致的。
由于 fetch 和 axios 等库在发送请求时会自动添加一些默认的请求头(例如 User-Agent、Accept 等),所以需要使用原生的 http 或 https 模块来完全自定义请求头,以模拟 curl 的行为。
方案概述
- 检查下
curl命令的请求头信息 - 检查下
Node.js发送请求时的默认请求头信息 - 使用
Node.js原生http/https模块模拟curl请求头
操作步骤
一、检查 curl 请求头信息
curl -i -L \
-H "Cache-Control: no-cache" \
"https://postman-echo.com/get"
结果为:
HTTP/2 200
date: Wed, 06 May 2026 01:48:24 GMT
content-type: application/json; charset=utf-8
content-length: 211
etag: W/"d3-AUU/yyEvf9ZFdY5bT0SSCCiSZaM"
vary: Accept-Encoding
x-envoy-upstream-service-time: 5
cf-cache-status: DYNAMIC
set-cookie: sails.sid=s%3A7xJIdDhvKLIN8E2dG23ItDxobnM4hC2Z.l8auv5RwpfiU%2F8MgZbzNGMsB1XvB3JJJV%2FlzU95S1DA; Path=/; HttpOnly
set-cookie: __cf_bm=qGkPwyouKlxvcQp7kDR2GcxRIhCMsA6Svh3idEGTrMQ-1778032104.5719283-1.0.1.1-296lNBK67RWUDWTs8_8HxHxQMiUZksUUk.Qwan0D5HY3u55M7cyZWEFEaT.137rd7qftHo9gkbUW225CurWE1gRSW1sL9dKfgtbI2Bq1Zd.nSxf1uXyiF84xi6iYGdF7; HttpOnly; Secure; Path=/; Domain=postman-echo.com; Expires=Wed, 06 May 2026 02:18:24 GMT
set-cookie: _cfuvid=n9vmhy0lLof.CDTzO6TBr80M591AEHHkMnjzWuMEjcA-1778032104.5719283-1.0.1.1-nzPqpCK8ZnHgFb24Ui7HnB0jLsFr7m.TsnaItYjTKPY; HttpOnly; SameSite=None; Secure; Path=/; Domain=postman-echo.com
server: cloudflare
cf-ray: 9f74528d9b2e67a7-SJC
{"args":{},"headers":{"host":"postman-echo.com","user-agent":"curl/8.5.0","cache-control":"no-cache","accept":"*/*","x-forwarded-proto":"https","accept-encoding":"gzip, br"},"url":"https://postman-echo.com/get"}
把请求头信息整理一下:
Host:postman-echo.comUser-Agent:curl/8.5.0Cache-Control:no-cacheAccept:*/*X-Forwarded-Proto:httpsAccept-Encoding:gzip, br
二、检查 Node.js 发送请求时的默认请求头信息
使用 axios 发送请求时的默认请求头信息:
const axios = require('axios');
axios.get('https://postman-echo.com/get')
.then(response => {
console.log(response.data);
})
.catch(error => {
console.error(error);
});
执行一下:
node test.js
结果为:
{
args: {},
headers: {
host: 'postman-echo.com',
'x-forwarded-proto': 'https',
accept: 'application/json, text/plain, */*',
'accept-encoding': 'gzip, br',
'user-agent': 'axios/1.16.0'
},
url: 'https://postman-echo.com/get'
}
这里可见有差异的请求头为:
User-Agent:axios/1.16.0Accept:application/json, text/plain, */*
三、使用 Node.js 原生 http/https 模块模拟 curl 请求头
const https = require('https');
const options = {
hostname: 'postman-echo.com',
path: '/get',
method: 'GET',
headers: {
// 模拟 curl 的请求头
'User-Agent': 'curl/8.5.0',
'Cache-Control': 'no-cache',
//
'Accept': '*/*'
}
};
const req = https.request(options, (res) => {
let data = '';
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
console.log(JSON.parse(data));
});
});
req.on('error', (e) => {
console.error(e);
});
req.end();
执行一下:
node test.js
结果为:
{
args: {},
headers: {
host: 'postman-echo.com',
'accept-encoding': 'gzip, br',
'user-agent': 'curl/8.5.0',
accept: '*/*',
'cache-control': 'no-cache',
'x-forwarded-proto': 'https'
},
url: 'https://postman-echo.com/get'
}
这样就成功模拟了 curl 的请求头,得到了与 curl 相同的响应结果。
结束。