Lambda调用时用JSON.parse(chunk)获取JSON文件报语法错误,本地测试正常
解决Lambda调用时HTTPS请求返回HTML而非JSON的问题
核心问题定位
报错Unexpected token < in JSON at position 0明确说明:你获取的响应不是预期的JSON,而是以<开头的HTML内容——大概率是CloudFront或S3返回的403/404错误页面。
本地/测试正常、实际调用异常的原因
- 权限与网络环境差异
本地和Lambda测试环境的IP可能在CloudFront/S3的访问白名单内,或是直接使用公网访问无限制;但实际运行的Lambda可能部署在VPC内,未配置NAT网关导致无法访问公网CloudFront,或是Lambda执行角色缺少访问该资源的权限,触发了权限拦截返回错误页。 - Event参数的隐性差异
即便你用了相同的测试Event,实际调用时event.detail.recording_s3_key_prefix可能存在编码问题、多余斜杠/空格,导致拼接后的URL无效,触发404错误页。 - 代码逻辑的隐患
你直接在data事件中解析chunk是错误的:data事件会分多次返回数据(文件较大时),本地测试因文件小可能一次返回完整内容,所以没暴露问题,但实际环境中可能出现分块,不过本次报错的核心原因还是HTML响应。
修复步骤
1. 先排查响应内容
在代码中添加日志,打印响应状态码和完整内容,明确错误类型:
const jsonURL = `https://XXXX.cloudfront.net/${event.detail.recording_s3_key_prefix}/events/recording-ended.json` https.get(jsonURL, res => { console.log('响应状态码:', res.statusCode); let rawData = ''; res.on('data', (chunk) => { rawData += chunk; }); res.on('end', () => { console.log('完整响应内容:', rawData); // 查看是否为HTML错误页 try { const json = JSON.parse(rawData); const duration = moment.utc(json.media.hls.duration_ms).format("HH:mm:ss"); // 后续业务逻辑 } catch (e) { console.error('解析错误:', e.message); } }); res.on('error', (err) => { console.error('请求错误:', err); }); })
查看CloudWatch日志中的响应内容,就能确定是403权限问题还是404路径问题。
2. 针对性解决权限/网络问题
- 若为403:检查CloudFront的Origin Access Identity(OAI)配置,确保S3桶策略允许OAI访问对应路径;若未使用OAI,确认S3桶的公开访问设置,同时给Lambda执行角色添加
s3:GetObject权限(针对S3直接访问场景)。 - 若Lambda在VPC内:配置NAT网关让Lambda能访问公网CloudFront,或是使用CloudFront的VPC端点实现私有访问。
3. 修正JSON解析逻辑
必须在end事件中拼接完所有chunk后再解析JSON,避免分块导致的解析失败,代码如上所示。
内容的提问来源于stack exchange,提问作者Shota Inoue
相关产品推荐
相关产品推荐

