How to make ajax call to AWS S3 bucket to get file names from folder?

454
January 13, 2017, at 03:09 AM

I am trying to get image file names from folder to add them dynamically as an HTML element to my web page. In order to do that, I found this piece of code which works perfectly on the local host.

    var folder = "img/gallery/";
    $.ajax({
        url: folder,
        success: function(data) {
            $(data).find("a").attr("href", function(i, val) {
                if (val.match(/\.(jpe?g|png|gif)$/)) {
                    // TODO: Filter and Title strings needs to be changed
                    var lightboxElement = "<img src=\"img\/gallery\/" + val + "\">";

                    $("#lightbox").append(lightboxElement);
                }
            });
        },
        error: function(exception) {
            console.log(data);
        }
    });

Basically, what this piece of code does is search different type of image files in a specified folder and returns their names. Then, an img element with image's source address added to the determined HTML object (#lightbox).

When I run the whole project on my local server, it works perfectly fine. However, when uploading it to AWS S3 bucket, that ajax call does not work. When I searched, I found a couple of possible solutions.

1) They suggest adding Cross-Origin Resource Sharing (CORS) file to the bucket. I added the file with the following rule. But it did not work.

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <CORSRule>
        <AllowedOrigin>*</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <AllowedHeader>*</AllowedHeader>
    </CORSRule>
</CORSConfiguration>

2) In the S3 bucket options, there is "Make Public" option. I used that option for both "img" and "gallery" folders and it did not work.

3) Some suggest using Amazon Route53 CNAME as a path for the folder which looks like this.

var folder = "http://example.com.s3-website-us-east-1.amazonaws.com/img/gallery/";

This also did not work.

Finally, below you can find two error messages I get when I load the page.

1) Failed to load resource: the server http://example.com/img/gallery/ responded with a status of 404 (Not Found)
2) Uncaught ReferenceError: data is not defined
    at Object.error (custom.js:21)
    at i (jquery.min.js:2)
    at Object.fireWith [as rejectWith] (jquery.min.js:2)
    at z (jquery.min.js:4)
    at XMLHttpRequest.<anonymous> (jquery.min.js:4)

Also, you can find the returned message from the Network tab of Chrome inspect below.

Code: NoSuchKey
Message: The specified key does not exist.
Key: img/gallery/index.html
RequestId: KSDJGSL3405309lkjLKJ087944GHFG654hJHGjhk8979
HostId: LD0349823=
An Error Occurred While Attempting to Retrieve a Custom Error Document
Code: NoSuchKey
Message: The specified key does not exist.
Key: error.html

Thanks in advance!

Answer 1

I would highly recommend against allowing public listings of bucket contents but if that is your intention, here is the solution:

Using the REST endpoint (not the web site endpoint) of the bucket (e.g. https://example-bucket.s3.amazonaws.com) your URL looks like this -- line breaks added for clarity.

https://example-bucket.s3.amazonaws.com/
?prefix=img/gallery/
&delimiter=/

This will return the first 1000 objects under /img/gallery (but note there is no leading / in the prefix).

This is the List Objects V1 API. For anonymous access, you don't need any AWS libraries... but you'll need to parse XML and handle the pagination.

http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketGET.html

There is also a V2 API, mentioned at the above page as well.

Rent Charter Buses Company
READ ALSO
JQuery-UI Widget undefined when using interval

JQuery-UI Widget undefined when using interval

I want to create a Jquery UI widget that starts an interval on creationThe function called on each interval timeout is supposed to be overrideable and therefore placed in the options object

441
dotdotdot render-blocking js

dotdotdot render-blocking js

When we use dotdotdot plugin to truncate text, it's recommended to include this plugin in <head> section and we should use $(document)ready(

479
Reset multiple select2 when loading array data

Reset multiple select2 when loading array data

I need to update an array data sourceUsing the reset/clear technique from http://stackoverflow

757