Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Accessing the Location header returned by AWS #150

Open
rossanthony opened this issue Mar 22, 2017 · 4 comments
Open

Accessing the Location header returned by AWS #150

rossanthony opened this issue Mar 22, 2017 · 4 comments

Comments

@rossanthony
Copy link

When uploading to S3 is there anyway to gain access to the header named Location which it returns containing the url encoded path to the file just uploaded?

@jamesfid
Copy link

Out of the box, the Uploader only resolves the XML payload to the didUpload callback and the promise. You can see where this happens here. It does not pass along the jqXHR object that would contain the headers.

Is there a reason you're not getting the URL from the XML payload? Looking at the headers versus the XML, the Location that AWS provides is the same in both. In my code, I get the URL similarly to what they show in the README here:

    uploader.on('didUpload', response => {
      // S3 will return XML with url
      let uploadedUrl = $(response).find('Location')[0].textContent;
      // http://yourbucket.s3.amazonaws.com/file.png
      uploadedUrl = decodeURIComponent(uploadedUrl);
    });

If you do need the actual headers, you'd have to extend the S3 Uploader and provide a new ajaxPromise and didUpload to get access to the jqXHR object. Even if you do this, you'll probably run into some CORS problems since the Location header will not be exposed by Access-Control-Expose-Headers by default. On S3 it's something with a CORS configuration including <ExposeHeader>, but I haven't done it myself.

@rossanthony
Copy link
Author

Thanks, I will try this method and pull out the location URL from the xml via the didUpload callback. I was initially (erroneously) expecting to be able to access the payload return by AWS in the .then() of the upload method, e.g:

uploader.upload(files[i]).then((data)=>{
     console.log(data);     // however this is undefined
}

@romulomachado
Copy link

I ran into a similar issue, S3 was returning an empty document with a 204 status code.

Setting success_action_status to '201' on the sign method made S3 return the XML document after the POST request.

def sign
  ...
  obj = resource.bucket(ENV['AWS_S3_BUCKET'])
    .object("uploads/#{params[:name]}")
    .presigned_post(
      acl: 'public-read', 
      expires: expires,
+     success_action_status: '201'
  )
  ...
end

Source: POST Object

@j15e
Copy link

j15e commented Mar 11, 2018

Please note the returned location header is encoded in a strict version where spaces are replace with +, which the decodeURIComponent method does not replace.

Not sure why S3 does this since spaces are allowed in HTTP headers and the description in the API documentation does not explain Location more than URI of the object. - Type: String.

Anyway, I suggest simply adding a replace like this if you want the fully decoded URI :

decodeURIComponent(response.headers.location.replace(/\+/g, ' '))

Edit: kind of official response of AWS on the + issue here : https://forums.aws.amazon.com/message.jspa?messageID=244233#244233

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants