Menu

Lambda関数URLをブラウザから起動した際に2回実行されることに対する対策

2024年3月20日に公開(2024年3月20日に更新)

概要

困っていること

AWS Lambdaの関数URLをブラウザ上から実行する際に、意図せず2回リクエストがLambdaに送られている。Lambdaの性質上基本的には2重起動しても問題ないように留意はしているが、無駄に実行する必要もないのでなんとかしたい。

構成図

関数URLを経由してLambdaを実行し、Discordに通知を送る。

解消方法

ポイント

ブラウザの仕様により、ブラウザがデフォルトで「favicon.ico」という名前のファビコン画像を自動で読み込むようになっている様子。その結果、HTTPリクエストが2回発生してしまい、2つのリクエストが同時に行われてしまう現象が起きていた。

解消方法としては、Lambdaからレスポンスを返す際にHTMLでfaviconの情報を含むレスポンスを返却する。

success = {
    'statusCode':200,
    'headers':{
            'Content-Type':'text/html'
    },
    'body': '<html><head><link rel="icon" href="data:,"></head><body>success</body></html>'
}

Lambda関数セットアップ

とりあえず最新のPythonで作成。

関数URLを有効化する。今回は認証は指定しない。

作成後、Lambdaレイヤーを追加。今回はrequestライブラリを使いたいためARNを指定する。

arn:aws:lambda:ap-northeast-1:770693421928:layer:Klayers-p312-requests:3

※別のPythonバージョンやアーキテクチャを利用する場合は下記から必要なレイヤーのARNを探す。
Klayers

ソースコード全体

import requests

# HTMLを返却する
# 関数URLをブラウザから実行した場合にfavicon.icoへのアクセスにより重複実行することを避ける
success = {
    'statusCode':200,
    'headers':{
            'Content-Type':'text/html'
    },
    'body': '<html><head><link rel="icon" href="data:,"></head><body>success</body></html>'
}

def lambda_handler(event, context):

    # ここにdiscordのwebhookURLを入力
    webhook_url = ""

    data = {'content': 'テストです'}
    _ = requests.post(webhook_url, json=data)
    return success

動作検証

faviconの情報を含むレスポンスを返却した結果

ブラウザ上でリクエストが1回だけ発生している。

Discordへの投稿も重複していない。

参考

©2023 Maya Hanada