Node.js请求Instagram ?__a=1接口在Vercel返回301无数据如何解决
问题根因
301状态码为永久重定向响应,原生Node.js的https.get方法默认不会自动跟随重定向,且301响应本身通常不会携带响应体,这就是你拿到空字符串、JSON.parse报错的直接原因。
本地运行正常是因为你本地IP访问Instagram的该接口时,平台未触发重定向规则;而Vercel无服务器函数的出口IP属于IDC机房IP,Instagram会对这类IP触发重定向逻辑,通常是跳转到地区对应子域名、或者要求携带合法请求头校验。
修复方案
首先要配置请求自动跟随重定向,同时补全模拟浏览器的合法请求头,绕过基础反爬校验。你之前用node-fetch未生效大概率是没有配置重定向跟随规则和请求头,修复后代码如下:
1. 基于node-fetch实现(推荐)
const fetch = require('node-fetch'); const getPostInfo = async (url) => { try { const res = await fetch(url, { // 开启自动跟随重定向 redirect: 'follow', // 模拟浏览器请求头,绕过基础反爬校验 headers: { 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 13_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8' } }); const data = await res.json(); return data; } catch (err) { console.log(err); throw err; } };
2. 基于原生https实现(手动处理重定向)
如果要保留原生https的实现方式,需要自行递归处理重定向地址:
const https = require('https'); const getPostInfo = (url) => { return new Promise((resolve, reject) => { const fetchUrl = (targetUrl) => { let data = ""; https.get(targetUrl, { headers: { 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 13_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36' } }, (res) => { // 处理3xx重定向响应 if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) { // 兼容相对路径的重定向地址 const redirectUrl = new URL(res.headers.location, targetUrl).href; return fetchUrl(redirectUrl); } res.on("data", (chunk) => { data += chunk.toString(); }); res.on("end", () => { try { const parsedData = JSON.parse(data); resolve(parsedData); } catch (parseErr) { reject(parseErr); } }); }).on("error", (err) => { reject(err); }); }; fetchUrl(url); }); };
注意事项
- Instagram的
__a=1接口属于未公开的私有接口,平台会不定期调整反爬策略,完成上述配置后如果出现403、429状态码,说明Vercel的IP段已被平台批量封禁,需要更换代理IP解决。 - Vercel无服务器函数默认执行超时时间为10秒,请求Instagram接口如果响应过慢可能触发超时,可根据需求自行调整函数的超时配置。
内容的提问来源于stack exchange,提问作者Shashank
相关产品推荐
相关产品推荐

