skip to Main Content

I’m generating a pre-signed url using java for an image stored in s3

  public String generateDownloadLink(String bucketName, String responseContentDisposition,
      String key, int days) {

    GetObjectRequest objectRequest =
        GetObjectRequest.builder()
            .bucket(bucketName)
            .responseContentDisposition(responseContentDisposition)
            .key(key).build();

    GetObjectPresignRequest preSignRequest =
        GetObjectPresignRequest.builder()
            .signatureDuration(Duration.ofDays(days))
            .getObjectRequest(objectRequest)
            .build();

    PresignedGetObjectRequest presignedRequest = this.s3Presigner.presignGetObject(preSignRequest);

    return presignedRequest.url().toString();

The FE (react) then loads the image using an image tag as in the image below.
This modal library also has a download button when opened in full screen -> the a tag element.
If the download button is pressed, it won’t download anything because of a CORS error.

This post explains why, though the solution can’t be applied in my case.

Also, this happens intermittently and i can’t figure out what is different in those cases.
Sometimes I can see the thumbnail (aka the library does an initial GET to load the image and display it) and also after the modal is opened, I can download the image (aka the libray does another get with the a tag).

enter image description here

Bucket CORS config

[
    {
        "AllowedHeaders": [
            "*"
        ],
        "AllowedMethods": [
            "PUT",
            "GET",
            "HEAD"
        ],
        "AllowedOrigins": [
            "http://localhost:3000",
            "https://<my-host>"
        ],
        "ExposeHeaders": [
            "ETag"
        ],
        "MaxAgeSeconds": 3000
    }

Edit:
I can’t add crossorigin="anonymous" because i don’t have access to the img element

3

Answers


  1. Try adding OPTIONS to the list of AllowedMethods in your CORS config. The CORS preflight request made from the browser(before the "real" request) uses OPTIONS http method, so it needs to be allowed.

    Login or Signup to reply.
  2. My suggestion would be to open the CORS policy up completely, if it begins to work then you can start to refine the access until you realize where the issue is:

    [
        {
            "AllowedHeaders": [
                "*"
            ],
            "AllowedMethods": [
                "*"
            ],
            "AllowedOrigins": [
                "*"
            ],
            "ExposeHeaders": [
                "*"
             
            ],
            "MaxAgeSeconds": 3000
        }
    ]
    

    This is also a good blog on CORS which may help:

    https://aws.amazon.com/blogs/media/deep-dive-into-cors-configs-on-aws-s3-how-to/

    You can also try adding crossorigin param to your image tag:

    <img src="my-img.s3.eu-west-2.amazonaws.com/img.png"
      crossorigin="anonymous" />
    
    Login or Signup to reply.
  3. You can force the browser to make the img tag use a CORS request when loading by setting the crossorigin attribute:

    <img src="foo.s3.eu-west-2.amazonaws.com/bar/baz"
      crossorigin="anonymous" />
    

    This stops the browser from treating the image as "tainted", but should also force s3 to return the appropriate CORS response that can be properly cached by the browser.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search