46

I'm using an AWS Lambda function to create a file and save it to my bucket on S3, it is working fine. After executing the putObject method, I get a data object, but it only contains an Etag of the recently added object.

s3.putObject(params, function(err, data) {
    // data only contains Etag
});

I need to know the exact URL that I can use in a browser so the client can see the file. The folder has been already made public and I can see the file if I copy the Link from the S3 console.

I tried using getSignedUrl but the URL it returns is used for other purposes, I believe.

Thanks!

Pablo Quemé
  • 1,414
  • 4
  • 16
  • 29
  • a presigned url can be used as a download link, however, it expires after x amount of minutes an works with non-public items. If your item is public, the easiest thing to do is simply concatenate the URL using the predictable pattern. – Taylor Ackley Jun 06 '17 at 21:53
  • 1
    *if I copy the Link from the S3 console* Do you see the pattern there? The URL for each object in the bucket follows exactly the same pattern. – Michael - sqlbot Jun 07 '17 at 00:18

3 Answers3

75

The SDKs do not generally contain a convenience method to create a URL for publicly-readable objects. However, when you called PutObject, you provided the bucket and the object's key and that's all you need. You can simply combine those to make the URL of the object, for example:

So, for example, if your bucket is pablo and the object key is dogs/toto.png, use:

Note that S3 keys do not begin with a / prefix. A key is of the form dogs/toto.png, and not /dogs/toto.png.

For region-specific buckets, see Working with Amazon S3 Buckets and AWS S3 URL Styles. Replace s3 with s3.<region>.amazonaws.com or s3-<region>.amazonaws.com in the above URLs, for example:

If you are using IPv6, then the general URL form will be:

For some buckets, you may use the older path-style URLs. Path-style URLs are deprecated and only work with buckets created on or before September 30, 2020. They are used like this:

Currently there are TLS and SSL certificate issues that may require some buckets with dots (.) in their name to be accessed via path-style URLs. AWS plans to address this. See the AWS announcement.

Note: General guidance on object keys where certain characters need special handling. For example space is encoded to + (plus sign) and plus sign is encoded to %2B. Also here.

jarmod
  • 71,565
  • 16
  • 115
  • 122
  • Thanks! I thought the link was prone to change unexpectedly in some naming scenarios. – Pablo Quemé Jun 07 '17 at 11:29
  • Additional post on naming considerations: https://stackoverflow.com/questions/7116450/what-are-valid-s3-key-names-that-can-be-accessed-via-the-s3-rest-api – jarmod Jun 07 '17 at 13:12
  • 1
    That doesn't explain what happens if for instance you use spaces in the name of the file you uploaded. Apparently they get replaced with '+', but maybe there are more rules like this? – Joris Mans Apr 10 '18 at 09:47
  • 1
    @JorisMans thanks, have added additional references. – jarmod Apr 10 '18 at 13:34
  • 3
    In my case I needed the bucket region too : `http://s3.region.amazonaws.com/bucket/key`. For me region was `eu-west-3` – Zenoo May 29 '19 at 14:54
9

in case you got the s3bucket and filename objects and want to extract the url, here is an option:

function getUrlFromBucket(s3Bucket,fileName){
    const {config :{params,region}} = s3Bucket;
    const regionString = region.includes('us-east-1') ?'':('-' + region)
    return `https://${params.Bucket}.s3${regionString}.amazonaws.com/${fileName}`
};
adir abargil
  • 5,495
  • 3
  • 19
  • 29
4

You can do an another call with this:

var params = {Bucket: 'bucket', Key: 'key'};
s3.getSignedUrl('putObject', params, function (err, url) {
  console.log('The URL is', url);
});
Helio Albano
  • 828
  • 9
  • 16