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).
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
Try adding
OPTIONS
to the list ofAllowedMethods
in your CORS config. The CORS preflight request made from the browser(before the "real" request) usesOPTIONS
http method, so it needs to be allowed.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:
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:You can force the browser to make the img tag use a CORS request when loading by setting the crossorigin attribute:
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.