下载亚马逊广告报告时的Authorization认证问题
解决亚马逊Sponsored Products API报告下载的InvalidArgument错误
问题原因分析
你遇到的这个InvalidArgument错误核心原因很明确:亚马逊S3返回的下载链接已经包含了完整的签名参数(也就是URL里的X-Amz-Algorithm、X-Amz-Signature这类查询串),这本身就是一种合法的认证方式。但如果你的下载请求同时带上了调用广告API时用的Authorization请求头,就等于同时使用了两种认证机制,触发了S3的校验规则,所以报错。
正确的Node.js下载实现
解决方法很简单:直接使用拿到的S3下载链接发起GET请求,不要添加任何额外的认证头,也不需要手动处理URL里的签名参数。下面是两种常见的实现示例:
用axios实现
const axios = require('axios'); const fs = require('fs'); async function downloadSponsoredProductsReport(s3DownloadUrl) { try { // 重点:移除所有自定义的Authorization头,直接使用带签名的URL const response = await axios.get(s3DownloadUrl, { responseType: 'stream' // 用流模式保存文件更高效 }); // 将报告流写入本地文件 const writeStream = fs.createWriteStream('./productAds_report.csv'); response.data.pipe(writeStream); writeStream.on('finish', () => { console.log('Product Ads报告下载并保存成功'); }); } catch (error) { console.error('下载失败:', error.response?.data || error.message); } } // 调用示例:传入你从API获取到的S3下载链接 downloadSponsoredProductsReport('你的S3下载链接');
用原生fetch实现
const fs = require('fs'); const { createWriteStream } = fs; async function downloadReportWithFetch(s3DownloadUrl) { try { const response = await fetch(s3DownloadUrl); if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`); const fileStream = createWriteStream('./report.csv'); await new Promise((resolve, reject) => { response.body.pipe(fileStream); fileStream.on('finish', resolve); fileStream.on('error', reject); }); console.log('下载完成'); } catch (err) { console.error('下载出错:', err); } }
参考PHP代码的思路验证
你提到的PHP仓库里的下载逻辑,核心思路和上面一致:它直接使用API返回的S3 URL发起请求,没有额外添加认证头,完全依赖URL自带的签名参数完成S3的身份校验。比如它的downloadReport方法就是通过curl直接请求该URL,没有手动设置Authorization相关的头信息,这也验证了我们的解决方案是正确的。
内容的提问来源于stack exchange,提问作者user8022517
相关产品推荐
相关产品推荐

