0

In my Angular application I try to upload a file to AWS-S3 with $http.put(url, file).

However it's not working, I get back a HTTP-403 Forbidden telling me that the signature s3 calculated differs from the one I provided BUT if I make the same request with curl like curl -X PUT -T file url then everything is ok the file gets uploaded. So either the way $http.put is working is bad (for this task) or curl has some magic. Can anyone elaborate?

2
  • Did you check stackoverflow.com/questions/2777078 ? Commented Jan 4, 2017 at 13:28
  • I checked it now, but none of the answers applies to my case. With curl I can make it work but not with $http :/ Commented Jan 4, 2017 at 13:58

2 Answers 2

1

When uploading a file with the $http service, it is important to set Content-Type: undefined.

  var config = { headers: {
                   "Content-Type": undefined,
                  }
               };

  var promise = $http.put(url, file, config);

The default content type for the $http service is application/json. By setting Content-Type: undefined, the $http service omits the Content-Type header and the XHR API sets the Content-Type header to that of the file.

Sign up to request clarification or add additional context in comments.

Comments

0

FYI:

I couldn't find out why $http is not working .. even I found strange things according to this topic.

So first I "fetched" the file from html like this:

<input flex="40" type="file" onchange="angular.element(this).scope().$parent.selectAttachment(this)">

becuase I didn't want to create a directive for this testing purpose. The selectAttachment function simply set the file as a property for my controller.

Then seemingly it was ok, I could read e.g this.attachment.name or this.attachment.size, but when I wrote $http.put(url, this.attachment) I got the signature-mismatch error.

Then I tried the same with XHR as in this tutorial: https://devcenter.heroku.com/articles/s3-upload-node

Never lucky...

Then, as a last resort, I tried to fetch the file by not setting it via angular but const file = document.getElementById('report-attachment').files[0]; and finally it worked for me. Intrestingly, fetching the file with getElementById AND using $http still not work, neither 1 or 2 3rd party angular uploader I tried, only with XHR o.o

The final "solution" which works for me:

HTML:

<input flex="40" id="report-attachment" type="file">

JS:

            const file = document.getElementById('report-attachment').files[0];
            const url = r && r.data;
            const xhr = new XMLHttpRequest();
            xhr.open('PUT', url);
            xhr.onreadystatechange = () => {
                if (xhr.readyState === 4) {
                    if (xhr.status === 200) {
                        console.debug('success');
                    } else {
                        console.error('error');
                    }
                }
            };
            xhr.send(file);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.