Search code examples
javascripttypescriptamazon-s3fetch-apimedia

Error when fetching and downloading images from CDN (S3) on Chrome and Safari


I have a fetch function which should download media files from an URL (S3 CDN).

It works perfectly on Firefox, but on Chrome and Safari it is causing a CORS error when downloading images (e.g. .png).

Videos (e.g. .mp4/.mov) for some reason seem to not be affected.

The Error looks like the following:

Access to fetch at '<url>.png' from origin '<domain>' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

The function does the following:

 const response = await fetch(mediaUrl);

  const blob = await response.blob();
  const downloadUrl = URL.createObjectURL(blob);
  const link = document.createElement('a');
  link.href = downloadUrl;
  link.download = this.getFileNameFromUrl(mediaUrl) || 'media';
  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);
  URL.revokeObjectURL(downloadUrl);

I am pretty sure that because of it working with video files it should not have to do something with the S3 CORS configuration, but you still find the CORS configuration below:

[
 {
    "AllowedHeaders": [
        "*"
    ],
    "AllowedMethods": [
        "PUT",
        "GET"
    ],
    "AllowedOrigins": [
        "<domain>"
    ],
    "ExposeHeaders": [
        "ETag"
    ]
 }
]

Solution

  • Maybe there is an easier way, but right now we just use to presign the URLs before fetching. That removes the error.

    https://docs.aws.amazon.com/AmazonS3/latest/userguide/ShareObjectPreSignedURL.html

    For node.js: https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/Package/-aws-sdk-s3-request-presigner/