I want to fetch images to display them on a local website for dev/test purposes before pushing the code to a more serious environment.
I am using the AWS JS SDK V3 on a Node web server and while 2 solutions come to mind, they both seem convoluted.
1 – Use GetObjectCommand
on my object, download it, make a blob/base64 encode, create a URL for my blob, and use that as my img src
attribute. I am not sure if downloading files on to the server to serve is best practice. In my mind since the S3 object already has a link to the image, it just makes sense if I could somehow embed that into the src
attribute. Unfortunately the SDK doesn’t seem to have any way to do this, beyond;
2 – Use the AWS CLI to presign an S3 bucket URL and use it. This works, and seems like a cleaner solution, but it needs a set duration and I would like the link to never expire. Also, it’s not very practical as I would need to presign a high number of S3 links and that is simply not practical.
I’ve enabled GET HTTP requests from * origins as a CORS policy on my bucket for the time being, but I’m pretty sure that’s not relevant because while it does let me use the SDK’s GetObjectCommand
functionality from an app running on localhost, the issue is I want something like img src=…
but it seems I need to pass appropriate headers to have access to the content, and without knowing which (if?) part of the SDK provides this functionality, I’m kind of stuck. This is also not a valid solution at all as realistically the bucket’s CORS policy should only allow requests from one origin – the actual website’s domain – and not every origin. So even if this let me send requests successfully, it wouldn’t be what I wanted.
Related questions:
- Failed GET requests to AWS S3 from website running on local host
It appears I have the same problem as this guy, but we’re using totally different architectures and I have no idea how his solution might apply to me. - Trouble Loading an Image from an Amazon S3 Bucket (without using the URL)
This guy seems to be trying to achieve the same goal as me, and went down the base64 route, but his question seems to be about a thing that is completely irrelevant to me - I need to view S3 images using react website
This guy seems to be in the exact same boat as me and, while he unfortunately has no answers, he does have a comment from Chris telling him in classic SO fashion that while he wants to do X, he should be doing Y instead and suggesting using Cognito as opposed to hard coded IAM role access credentials to access an item which is a fair suggestion, but has absolutely nothing to do with ducati1212’s problem. He then proceeds to recommend using Cloudfront to serve the images which, again, seems like a fair suggestion and apparently worked but I am not at the point in my app where I have began using a CDN to serve images yet, so maybe I’ll read more into it later but for now it is completely irrelevant to me.
2
Answers
The answer is: don’t. If it’s a public bucket use the URL. If it’s a private bucket you’re gonna have to handle signed URL’s which last up to 1 week max.
The public URL is now formed like: https://bucket-name.s3.amazonaws.com/key-name.
So: if your bucket is
example
and the object key is tree/oak.png, use:Realistically and practically speaking, for website/web app media – just don’t use any providers bucket storage offering. Use plain old static web storage from your web server. For Nodejs, that’s the ‘fs’ module. For NGINX it’s the http core module. Just keep it simple in my opinion. I’ve used Google’s Cloud Storage before for web media and it started breaking (expiring) and it was just not worth the hassle. If you want accounting (media/image access records) you can roll your own logging solution.
I’ve had the same problem before, i was creating an Website-HomePage-Printer,
and run through some trouble to draw the images out of the URLS
I reached into 2 ways to extract img from URL:
But first:
1- Through canvas element
Embedding an image via data: URL:
Another possible way to include images is via the data: URL. Data URLs allow you to completely define an image as a Base64 encoded string of characters directly in your code.
Data URLs are composed of four parts: a prefix (data:), a MIME type indicating the type of data, an optional base64 token if non-textual, and the data itself:
The mediatype is a MIME type string, such as ‘image/jpeg’ for a JPEG image file. If omitted, defaults to ”text/plain;charset=US-ASCII”
Canvas MDN
2-Through a use of an headless browser and puppeteer package
You can basically get any data you have access to and screenshot it for example.
Github Examples
EXTRA
If you are having problems with getting the object, my advice is to read this documentation GetObjectsAPI and check your ACL GetObjectAcl again, check your permissions on AWS, keys, etc etc.
[Junior Dev btw, forgive me for any misinterpretations]