JavaScriptでAmazon S3の画像を取得して表示したい。
JavaScriptでAmazon S3の画像を取得してみる。
const img = new Image();
img.crossOrigin = "anonymous";
img.addEventListener('load', () => this._setImage(img));
img.src = imgSrc;
すると、以下のエラーが発生した。
Access to image at 'https://xxx.s3.ap-northeast-1.amazonaws.com/' from origin 'https://xxx' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
- AWS マネジメントコンソールにログインして、「Amazon S3」→「パケット」にアクセスする。
- 対象のパケットを開く。
- 「アクセス許可」の「Cross-Origin Resource Sharing (CORS)」の「編集」ボタンを押し、以下の設定を入力して、「変更の保存」ボタンを押す。
[
{
"AllowedHeaders": [
"*"
],
"AllowedMethods": [
"GET",
"HEAD"
],
"AllowedOrigins": [
"*"
],
"ExposeHeaders": [
"Access-Control-Allow-Origin"
]
}
]
アクセス元のドメインを制限する場合は、AllowedOriginsにアクセスを許可するドメインを設定する。
例:example.comからのアクセスのみ許可する
[
{
"AllowedHeaders": [
"*"
],
"AllowedMethods": [
"GET",
"HEAD"
],
"AllowedOrigins": [
"example.com"
],
"ExposeHeaders": [
"Access-Control-Allow-Origin"
]
}
]
以上の設定を行うと、エラーは発生しなくなる。
しかし、それでもたまにエラーが発生した。
調べてみると、Chromeのキャッシュの挙動に問題があるようだ。
- 参考
S3のPresigned URLを使用しているため、画像のURLの末尾にクエリパラメーターを付与するという案は、使えなかった。
Presigned URLにクエリパラメーターを付与するとエラーになる。
img.src = `${imgSrc}&x=${Date.now()}`;
最終的には、画像のURLを使い回さず、画像を表示するたびに新しいURLを作成するようにして対応した。