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

使用AWS SDK v3向LocalStack SQS发消息时遇反序列化错误

问题

运行Express.js应用,尝试使用AWS SDK v3将字符串化对象消息推送到LocalStack的SQS队列中。已通过awslocal sqs create-queue --queue-name my-queue命令创建队列,依赖版本为"@aws-sdk/client-sqs": "^3.428.0",但出现以下错误:

SyntaxError: Unexpected token '<', "<?xml vers"... is not valid JSON
Deserialization error: to see the raw response, inspect the hidden field {error}.$response on this object.
at JSON.parse

附带代码:

app.js

const express = require("express");
const { SQS, SendMessageCommand } = require("@aws-sdk/client-sqs");

const app = express();
const port = 3000;

// Define the LocalStack SQS endpoint
const localStackEndpoint = "http://localhost:4566";

// Configure the SQS client
const sqs = new SQS({
  region: "us-east-1", // Specify any region (LocalStack doesn't enforce region constraints)
  endpoint: localStackEndpoint,
});

// Route to send a message to the SQS queue
app.post("/test", async (req, res) => {
  try {
    // Specify the URL of your LocalStack SQS queue
    const queueUrl = `${localStackEndpoint}/000000000000/my-queue`;

    // Define the message body
    const messageBody = "Hello, LocalStack!";

    // Create the SendMessageCommand
    const sendMessageCommand = new SendMessageCommand({
      QueueUrl: queueUrl,
      MessageBody: messageBody,
    });

    // Send the message
    const sendMessageResponse = await sqs.send(sendMessageCommand);

    console.log("Message sent successfully:", sendMessageResponse);

    res.send("Message sent successfully");
  } catch (error) {
    console.error("Error sending message:", error);
    res.status(500).send("Error sending message");
  }
});

// Start the server
app.listen(port, () => {
  console.log(`Server is running at http://localhost:${port}`);
});

docker-compose.yml

version: '3'
services:
  localstack:
    image: localstack/localstack
    ports:
      - '4566-4599:4566-4599'
      - '8080:8080'
    environment:
      - SERVICES=sqs
      - DEBUG=1
      - DATA_DIR=/tmp/localstack/data
      - PORT_WEB_UI=8080
    volumes:
      - '${TMPDIR:-/tmp/localstack}:/var/lib/localstack'
解决方案

该错误是因为AWS SDK v3收到了LocalStack返回的XML格式响应,而非预期的JSON,核心原因是客户端配置缺失或队列URL构造错误。以下是修复步骤:

1. 完善SQS客户端配置

AWS SDK v3需要凭证信息才能发起请求,即使LocalStack不验证真实凭证,也需提供占位值;同时开启路径风格适配,确保请求符合LocalStack的接口规范:

const sqs = new SQS({
  region: "us-east-1",
  endpoint: localStackEndpoint,
  credentials: {
    accessKeyId: "test",
    secretAccessKey: "test"
  },
  forcePathStyle: true // 强制使用路径风格的endpoint,适配LocalStack
});

2. 动态获取队列URL

避免硬编码队列URL导致格式错误,改用GetQueueUrlCommand从LocalStack获取正确的队列地址:

// 先导入GetQueueUrlCommand
const { SQS, SendMessageCommand, GetQueueUrlCommand } = require("@aws-sdk/client-sqs");

// 在/test路由中替换硬编码的queueUrl
const getQueueUrlCmd = new GetQueueUrlCommand({ QueueName: "my-queue" });
const queueUrlResult = await sqs.send(getQueueUrlCmd);
const queueUrl = queueUrlResult.QueueUrl;

修复后的完整app.js

const express = require("express");
const { SQS, SendMessageCommand, GetQueueUrlCommand } = require("@aws-sdk/client-sqs");

const app = express();
const port = 3000;

const localStackEndpoint = "http://localhost:4566";

const sqs = new SQS({
  region: "us-east-1",
  endpoint: localStackEndpoint,
  credentials: {
    accessKeyId: "test",
    secretAccessKey: "test"
  },
  forcePathStyle: true
});

app.post("/test", async (req, res) => {
  try {
    // 动态获取队列URL
    const getQueueUrlCmd = new GetQueueUrlCommand({ QueueName: "my-queue" });
    const queueUrlResult = await sqs.send(getQueueUrlCmd);
    const queueUrl = queueUrlResult.QueueUrl;

    const messageBody = "Hello, LocalStack!";
    const sendMessageCommand = new SendMessageCommand({
      QueueUrl: queueUrl,
      MessageBody: messageBody,
    });

    const sendMessageResponse = await sqs.send(sendMessageCommand);
    console.log("Message sent successfully:", sendMessageResponse);
    res.send("Message sent successfully");
  } catch (error) {
    console.error("Error sending message:", error);
    res.status(500).send("Error sending message");
  }
});

app.listen(port, () => {
  console.log(`Server is running at http://localhost:${port}`);
});

验证

重启Express应用,调用POST /test接口,查看控制台日志是否输出消息发送成功的信息,同时可通过awslocal sqs receive-message --queue-name my-queue命令验证队列中是否收到消息。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 14:23:15