You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AWS SNS订阅确认POST请求至Node.js API路由时请求体为空/未定义

解决AWS SNS订阅确认请求体在Node.js API中为空的问题

问题原因

从你提供的curl请求可以看到,AWS SNS发送的POST请求Content-Type是text/plain; charset=UTF-8,而大多数Node.js Web框架(比如Express)默认只配置了解析application/json类型的请求体,无法正确解析SNS的文本格式请求体,导致获取到空或未定义的请求体。

解决方案

1. 配置文本请求体解析中间件

如果使用Express框架,需要添加解析text类型请求体的中间件,将接收到的文本内容转换为JSON对象:

const express = require('express');
const app = express();

// 解析text/plain类型的请求体
app.use(express.text({ type: 'text/plain' }));

// 将解析后的文本转为JSON对象
app.use((req, res, next) => {
  if (req.is('text/plain')) {
    try {
      req.body = JSON.parse(req.body);
    } catch (err) {
      console.error('解析SNS请求体失败:', err);
      return res.status(400).send('无效的请求体格式');
    }
  }
  next();
});

// SNS通知处理路由
app.post('/api/SESNotifications', (req, res) => {
  console.log('收到SNS请求:', req.body);
  
  // 处理订阅确认请求
  if (req.body.Type === 'SubscriptionConfirmation') {
    console.log('待确认订阅URL:', req.body.SubscribeURL);
    // 需向该URL发起GET请求完成订阅(可使用axios/node-fetch等工具)
    res.status(200).send('确认收到');
  } else if (req.body.Type === 'Notification') {
    console.log('收到通知内容:', req.body.Message);
    res.status(200).send('处理完成');
  } else {
    res.status(400).send('未知的消息类型');
  }
});

app.listen(5000, () => {
  console.log('服务器运行在端口5000');
});

2. 关键注意事项

  • 中间件顺序不能错:先解析text内容,再转为JSON,最后处理路由
  • 订阅确认必须完成:只有向SubscribeURL发起GET请求,AWS SNS才会停止发送确认请求
  • 可选添加签名验证:验证请求签名,确保请求确实来自AWS SNS,避免伪造请求

内容的提问来源于stack exchange,提问作者Rajat Agarwal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 05:44:57