NodeJS 无法将请求正文解析为json:意外字符(\'-\'(代码45))AWS Lambda + API + Postman

eni9jsuy  于 2023-06-22  发布在  Node.js
关注(0)|答案(5)|浏览(169)

我已经尝试了几天从AWS中的API网关发送到Lambda函数的参数,但没有成功。
我决定从头开始,所以我遵循了他们的演练(http://docs.aws.amazon.com/apigateway/latest/developerguide/getting-started.html #getting-started-new-lambda)
我已经检查了此演练两次,并且已经按照步骤进行了操作。

问题

当我在Postman或Swift中测试API时,我得到错误:
{"message ":"无法将请求正文解析为json:数值中出现意外字符('-'(代码45)):减号后面应该有数字(0 - 9),用于[Source:[B@c036d15;行:1,列:3]"}
在Postman中,当我以JSON格式查看结果时,我只会得到
错误字符串

Lambda函数

该函数是演练中的基本示例:

console.log('Loading event');

exports.handler = function(event, context) {
  var name = (event.name === undefined ? 'No-Name' : event.name);
  console.log('"Hello":"' + name + '"');
  context.done(null, {"Hello":name}); // SUCCESS with message
};

当从Lambda控制台测试并使用测试数据时,我得到的结果是:

{
    "Hello": "TestUser123"
}

当从API网关测试进行测试时,结果也是:

{
    "Hello": "TestUser123"
}

有人能明白为什么两个测试控制台都允许这项工作,但当用POSTMAN测试或在Swift脚本中使用时,它不起作用吗?

编辑1

在postman中,我将content-type设置为application/json
脚本返回默认值:

{
    "Hello": "user"
}

但是,当我在POSTMAN中添加参数nameTestUser123时,它返回错误。

更新1

好吧,所以我把Map模板改成了我在另一个答案中找到的模板:

{ "name": "$input.params('name')" }

现在的结果是:

{
   "Hello": ""
}

有什么想法为什么它没有得到的名字?

kcrjzv8t

kcrjzv8t1#

我今天被这事缠住了。
您的Map模板为:

{ "name": "$input.params('name')" }

AWS使用AWS Velocity模板;虽然看起来像JSON,但它是不同的。
如果使用

{ "name": $input.params('name') } // notice no quotes

对于Map模板,那么它应该按预期工作。

vsikbqxv

vsikbqxv2#

非常仔细地阅读错误消息,它实际上告诉了你问题所在。例如,我得到了
无法将请求正文解析为json:意外字符('"'(代码34)):需要用逗号分隔对象条目
所以问题是我少了一个逗号。我检查了我的Lambda的集成请求- Body Mapping模板

{
"age" : $input.json('$.persondata.age'),
"income" : $input.json('$.persondata.income')
"height" : $input.json('$.persondata.height')
}

你能发现问题吗?我在收入线后面少了一个逗号。
这是另一个例子。
无法将请求正文解析为json:意外字符('}'(代码125)):期望值
当我看到集成请求- Body Mapping模板时:

#set($inputRoot = $input.path('$'))
{
  "age" : $inputRoot.age,
  "height" : $inputRoot.height,
  "income" : $inputRootincome
}

你能发现问题吗?我在$inputRootincome中缺少一个点。

eivnm1vs

eivnm1vs3#

错误消息:

Could not parse request body into json: Could not parse payload into json: Unrecognized token \' \': was expecting (\'true\', \'false\' or \'null\')

错误原因:当json中的字符串值没有在awsMap模板中使用双引号赋值时,就会发生错误。
解决方案:(请注意:本例针对application/json类型请求模板)
实际上这个问题的解决方案是,如果你在json中使用字符串类型的值,那么它的值应该在Map模板中的(“”-双引号)内赋值。
下面示出的示例具有以下属性:

customerId - string (Please note : this value comes from a query parameter)
customerName - string
customerAge - integer
isPermanentEmployee - boolean
customerAddress - string (Please note this is an optional parameter)

并且Map模板应该像下面所示的示例那样定义
参考以下示例:

#set($inputRoot = $input.path('$'))
{
  "CustomerId": "$input.params('customerId')",
  "CustomerName": "$inputRoot.customerName",
  "CustomerAge": $inputRoot.customerAge,
  "IsPermanentEmployee": $inputRoot.isPermanentEmployee
  "CustomerAddress ": #if($inputRoot.customerAddress == "") "" #elseif($inputRoot.customerAddress != "") "$inputRoot.customerAddress" #end
}

如果您注意到上面的Map模板,我会在双引号(“”)内给出字符串值,这将解决错误
这个例子还包含了如何使用#if#else语句处理AWSMap模板中的可选参数。

wmomyfyw

wmomyfyw4#

很可能您在API网关中的“集成请求”中复制粘贴了多行。
当复制一行并将其粘贴到下面时,您可能复制了该行末尾的隐藏字符'\n'。这可能会导致lambda函数出现问题。

示例:复制包含age的行并粘贴两次,并将它们分别修改为height和income。

#set($inputRoot = $input.path('$'))
{
  "age" : $inputRoot.age,
  "height": $inputRoot.height,
  "income": $inputRoot.income
}

不用复制粘贴,只需为heightincome键入行。

dm7nw8vv

dm7nw8vv5#

我今天遇到了这个问题,这是因为我在API设置中将二进制媒体类型设置为 /

相关问题