AWS Lambda 错误:当 url 参数包含 JSON 数组时,“无法将请求正文解析为 json”
Posted
技术标签:
【中文标题】AWS Lambda 错误:当 url 参数包含 JSON 数组时,“无法将请求正文解析为 json”【英文标题】:AWS Lambda Error : 'Could not parse request body into json ' when url parameter contains JSON array 【发布时间】:2017-01-10 11:42:49 【问题描述】:我正在尝试通过传递如下参数来调用我的 Lambda 函数。它包含 撇号(')。
https://invoke_url?param=[["kurlo jack's book","Adventure Books",8.8,1]]
字符串化为'https://invoke_url?param=%5B%5B%229780786706211%22s....`
我使用下面的映射将参数传递给 lambda
"query":
#foreach($queryParam in $input.params().querystring.keySet())
"$queryParam": "$util.escapejavascript($input.params().querystring.get($queryParam))" #if($foreach.hasNext),#end
#end
我收到以下错误
"message": "Could not parse request body into json: Unrecognized character escape \'\'\' (code 39)\n at [Source: [B@5b70c341; line: 29, column: 65]"
从映射模板中删除双引号后,我也尝试过。但是没用。
【问题讨论】:
你能在字符串被解析之前打印它吗? @johni 有没有办法在 api 网关集成请求映射上做到这一点? 应该有。我不是 Api Gayeway 专家,但从我过去几天研究的材料来看,似乎对此有支持。无论如何,我认为您的问题与您要解析的字符串有关。没有别的,这根本与 AWS 无关(IMO) 这应该可以回答您关于 Api Gateway ***.com/q/31329958/3454745 的问题 我们是否必须将字符串解码回 API Gateway 的 json 模板部分?还是它在内部解决这个问题? 【参考方案1】:“查询字符串”(超链接中?
之后的部分)必须是string
。无论您构造什么,都必须附加到它上面:https://invoke_url?a=x&b=y
在您的 Lambda 代码中放置:
if( event.hasOwnProperty( 'params' ) )
if( event.params.hasOwnProperty( 'querystring' ) )
params = event.params.querystring;
(显然是一些无关的检查,可能没有必要,但是呃)
在您的 API 网关中转到:
APIs -> api_name -> Resources -> invoke_url -> GET -> Method Execution
在 URL 查询字符串参数下“添加查询字符串”a
和 b
(或其他)
当您点击www.com/invoke_url?a=x&b=y
时,您现在可以通过以下方式访问它们:
...
params = event.params.querystring;
console.log( params.a, params.b );
...
【讨论】:
实际上我正在发送这样的参数:invok_url?param=%5B%5B%229780786706211%22%2C%22Endurance%3A%20Shackleton%27s%20Incredible%20Voyage%22%2C%22Adventure%20Books %22%2C8.8%2C1%5D%5D【参考方案2】:我没有解决方案,但我已经缩小了根本原因。 Lambda 似乎不喜欢用单斜杠转义单引号。
如果您将映射模板硬编码为如下所示:
"query-fixed":
"param": "[[\"kurlo jack\\'s book\",\"Adventure Books\",8.8,1]]"
我的测试 Lambda 调用成功。但是,如果您将模板硬编码为:
"query-fixed":
"param": "[[\"kurlo jack\'s book\",\"Adventure Books\",8.8,1]]"
我收到与您在上面收到的相同的错误消息。不幸的是,第二种变体是 API Gateway 为 Lambda 调用生成的。
解决方法可能涉及使用模板将用斜杠转义的单引号替换为两个斜杠。见Replace a Substring of a String in Velocity Template Language
我会在内部跟进 Lambda 并在我听到任何消息或有功能性解决方法时进行更新。
【讨论】:
它确实帮助我解决了这个问题。我已经在你的回答中更新了解决方案【参考方案3】:尝试根据this W3Schools page 中定义的内容将'
的编码更改为 %27(具有讽刺意味的是,他们的示例也没有对单引号进行编码,我猜它是因为它属于“支持”的 ASSCI 集字符)
【讨论】:
【参考方案4】:请务必在.escapeJavaScript(data)
之后将.replaceAll("\\'","'")
添加到您的请求正文直通模板中
我从 AWS 的文档中发现这一点对这个问题非常有帮助:
$util.escapeJavaScript()
使用 JavaScript 字符串规则转义字符串中的字符。
注意此函数会将任何常规单引号 (') 转换为 转义的 (\')。但是,转义的单引号在 JSON。因此,当此函数的输出用于 JSON 属性,您必须将任何转义的单引号 (\') 转回常规 单引号 (')。这在以下示例中显示:
$util.escapeJavaScript(data).replaceAll("\\'","'")
【讨论】:
我正在尝试这个,但我只是收到内部服务器错误。"query": #foreach($queryParam in $input.params().querystring.keySet()) "$queryParam": "$util.escapeJavaScript($input.params().querystring.get($queryParam)).replace(\"\\'\",\"'\")" #if($foreach.hasNext),#end #end
以上是关于AWS Lambda 错误:当 url 参数包含 JSON 数组时,“无法将请求正文解析为 json”的主要内容,如果未能解决你的问题,请参考以下文章
Terraform:为调用 Lambda 的 AWS API Gateway 创建 url 路径参数?
使用 graphql、aws lambda 和无服务器框架的多个 url 路径选项错误
如何使用 GET 请求将参数传递给 AWS Lambda 函数?
AWS Lambda - 访问被拒绝错误 - GetObject