フロントエンドからPOST通信でアクセスするAPIをLambda+APIGatewayで作っていた時にハマった話を備忘録
申し込みフォームで登録後に完了メール送信を行うロジックを作っていた。
const onSubmit = async () => {
const params = {
to: email,
name: name,
email: email,
tel: tel,
zipcode: zipcode,
address: prefecture + " " + address,
message: message,
};
const res = await axios.post(
"https://sample/send",
params,
{
headers: { "Content-Type": "multipart/form-data; charset=UTF-8" },
}
);
}
Lamda側でeventの中身をのぞいてみると。。。
リクエストbodyにJSON形式で渡されると思いきや、エンコードされた状態でパラメータが渡っていたため
Lambda側でどのようにパラメータ取得を行えばよいかわからず調べること1時間...
{
'body': 'eyJ0byI6InNhbXBsZUBnbWFpLmNvbSIsIm5hbWUiOiLlkI3liY0iLCJlbWFpbCI6InNhbXBsZUBnbWFpLmNvbSIsInRlbCI6Ijk5OTk5OTk5OTk5IiwiemlwY29kZSI6IjIxMDAwMDgiLCJhZGRyZXNzIjoi5p2x5Lqs6YO9IOS9j+aJgDHkuIHnm64iLCJtZXNzYWdlIjoi55Sz44GX6YCB44KK5LqL6aCFIn0=',
'isBase64Encoded': True
}
base64モジュールによりデコード処理を行うことで解決できることがわかった。
def send_mail(event, context):
body = event["body"]
#bodyのエンコードされた文字列をJSON文字列にデコードし、辞書型に変換
params = json.loads(base64.b64decode(body).decode('utf-8'))
TO = params["to"]
name = params["name"]
email = params["email"]
tel = params["tel"]
zipcode = params["zipcode"]
address = params["address"]
message = params["message"]
##以下割愛
HTTPの仕組みは奥が深い....
POSTするさいのHTTPヘッダーのContent-Typeも重要であることが分かった。
何がどう異なるのかは調べなければ...