curl调用Shopee API正常但node-fetch失败的问题排查
解决node-fetch调用Shopee API返回90309999错误的问题
curl能正常请求但node-fetch v2.6.1返回90309999,核心原因就是两者发送的请求存在细微差异,被Shopee的反爬机制拦截了。结合你的情况,重点排查以下几个方向:
1. 核对请求头的完全一致性
Shopee的API对请求头的校验非常严格,哪怕一个字段的细微差异都会触发拦截。你需要:
- 把curl里的
af-ac-enc-dat、cookie、user-agent原封不动复制到node-fetch中,不要做任何修改,包括空格、特殊字符 - 补充curl默认携带的通用请求头,比如
Accept: */*、Accept-Encoding: gzip, deflate, br、Connection: keep-alive,这些头curl会自动添加,但node-fetch的默认值可能不同
2. 检查Cookie的处理方式
node-fetch对Cookie头的处理和curl可能存在差异:
- 确保Cookie字符串完整,没有遗漏任何键值对,顺序也要和curl里的一致
- 不要对Cookie里的特殊字符做转义,直接复制curl中的原始字符串
3. 模拟curl的请求头顺序
虽然HTTP标准里请求头顺序不影响,但部分网站的反爬会校验头的顺序。你可以用Headers对象手动按curl的顺序添加头:
const headers = new Headers(); headers.append('af-ac-enc-dat', '你的加密字符串'); headers.append('cookie', '你的完整Cookie字符串'); headers.append('user-agent', '你的User-Agent'); headers.append('Accept', '*/*'); headers.append('Accept-Encoding', 'gzip, deflate, br'); headers.append('Connection', 'keep-alive');
4. 启用压缩适配
curl默认支持压缩,node-fetch v2需要显式开启compress: true,否则可能因为Accept-Encoding头不匹配被拦截:
const response = await fetch(url, { method: 'GET', headers: headers, compress: true });
完整示例代码
const fetch = require('node-fetch'); async function getShopeeItem() { const url = 'https://shopee.co.th/api/v4/item/get?itemid=1420642134&shopid=84822794'; const headers = new Headers(); headers.append('af-ac-enc-dat', 'YOUR_ENC_DAT'); headers.append('cookie', 'YOUR_FULL_COOKIE_STRING'); headers.append('user-agent', 'YOUR_USER_AGENT'); headers.append('Accept', '*/*'); headers.append('Accept-Encoding', 'gzip, deflate, br'); headers.append('Connection', 'keep-alive'); try { const response = await fetch(url, { method: 'GET', headers: headers, compress: true }); if (!response.ok) { console.log('错误状态码:', response.status); console.log('响应内容:', await response.text()); return; } const data = await response.json(); console.log('商品数据:', data); } catch (err) { console.error('请求异常:', err); } } getShopeeItem();
额外排查点
如果以上步骤都没用,建议抓包对比curl和node-fetch的请求详情:
- 用
tcpdump或者Wireshark捕获两种请求的数据包,对比HTTP头的每一个字段 - 检查是否存在node-fetch自动添加的额外头(比如
Host头是否正确,有没有多余的字段)
内容的提问来源于stack exchange,提问作者Giuk Kim
相关产品推荐
相关产品推荐

