Uploading files to AWS-S3 using Angular $http PUT method: A step-by-step guide

When attempting to upload a file to AWS-S3 using $http.put(url, file) in my Angular application, I encounter an issue. The HTTP-403 Forbidden error message indicates that the signature calculated by S3 differs from the one I provided. However, if I use curl for the same request like curl -X PUT -T file url, the file uploads successfully without any issues. This raises the question of whether $http.put is not ideal for this task or if curl has some special functionality. Can someone provide more insight on this?

Answer №1

When using the $http service to upload a file, it is crucial to specify Content-Type: undefined.

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

  var request = $http.put(url, file, settings);

The default content type for the $http service is application/json. Setting Content-Type: undefined allows the file's format to be defined by XHR API instead of automatically assuming json.

Answer №2

Just a heads up:

I searched high and low to figure out why $http wasn't cooperating...I even stumbled upon some strange findings related to this issue.

Initially, I decided to "fetch" the file from HTML in this manner:

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

I opted not to create a directive for testing purposes. The function selectAttachment simply assigned the file as a property for my controller.

Everything seemed fine at first—I could access attributes like this.attachment.name or this.attachment.size, but when I attempted $http.put(url, this.attachment), I encountered a signature-mismatch error.

Next, I followed a tutorial using XHR similar to this one: https://devcenter.heroku.com/articles/s3-upload-node

No luck there...

As a final attempt, I tried fetching the file without setting it via angular using

const file = document.getElementById('report-attachment').files[0];
Lo and behold, it worked! Interestingly enough, retrieving the file with getElementById AND utilizing $http still didn't work, nor did any of the 1st or 2nd party Angular uploaders I tested—only XHR o.o

The ultimate workaround that did the trick:

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);

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Limiting the display of every item in Angular ngFor

I'm currently working with Angular and I have the following code in my component.html: <div class="card" *ngFor="let item of galleries;" (mouseenter)=" setBackground(item?.image?.fullpath)" (mouseover)="showCount ...

Ways to eliminate the top space in the background image

After implementing a basic HTML code to add a background image to my webpage, I noticed there is still some empty space at the top of the page. I attempted to adjust the position of the background image using the following code, but it only lifted it upwar ...

An error was encountered while attempting to utilize Google's Core Reporting API: Uncaught SyntaxError: Unexpected token <

I've been experimenting with Google's Core Reporting API and successfully implemented their provided demo. Now, I'm trying to integrate the code into my own project. My main tech stack includes AngularJS and PHP. I aim to keep it simple by ...

Why is my Ajax utilizing PHP _POST not functioning as expected?

I am facing an issue with the JavaScript code below: <script src='https://ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.min.js'></script> <script> function deletUserInfo(id_user){ console.log(id_user); ...

Issue with Bootstrap 4.2 modal: Unable to edit input fields, button cannot be clicked, modal does not close

https://i.sstatic.net/vHnVG.png https://i.sstatic.net/MhU3f.png Utilizing Bootstrap 4.2.1, I have a modal that opens via a specific link: <a href="#" data-toggle="modal" data-target="#inviteByEmailPopup" data-backdrop="false" data-keyboard="false"> ...

`Using top-level await in a module can interfere with the firing of the `onload` event

It seems that the load event is not triggering when I use await for an IndexedDB opening at the top level within an indirectly loaded module. Interestingly, if I remove the await, the load handler works as expected. Similarly, replacing the openDB call wi ...

When a parent document is deleted, Mongoose automatically removes any references to child documents

Greetings everyone, thank you for taking the time to read my query. I am looking to remove a child object that is referenced in a parent object. Below is the structure: const parentSchema: = new Schema({ name: String, child: { type: mongoose.Schema. ...

Combining null and decimal validation into a single function in Asp .Net - JavaScript

How can I ensure that my Textbox is validated using Javascript? Specifically, I want to make sure that the TextBox is not empty and that only two digits are allowed after the decimal point. Additionally, I would like to restrict any other characters exce ...

Steps to creating an elliptical border using CSS

Is there a way to apply CSS styles specifically to the left border of a div to achieve an elliptical shape, while keeping other borders normal? I've managed to create a semi-ellipse with the following code, but the rest of the border remains unchanged ...

Inconsistent Functionality of Bootstrap Popover

I am experiencing an issue with the bootstrap Popover feature. It seems to work inconsistently - sometimes it works and other times it doesn't. I am using it to create a popover that displays a user's information when a visitor hovers over the us ...

Arranging buttons that are generated dynamically in a vertical alignment

Currently, I am in the process of creating a webpage for various items, and everything is going well so far. However, I have encountered an issue while attempting to vertically align the buttons that I am generating using JavaScript within the document. I ...

Running Windows commands from Node.js on WSL2 Ubuntu and handling escape sequences

When running the following command in the CMD shell on Windows, it executes successfully: CMD /S /C " "..\..\Program Files\Google\Chrome\Application\chrome.exe" " However, attempting to run the same comman ...

The MUI Slide Transition experiences a malfunction when using multiple Slide components simultaneously

I'm having trouble getting the animations to work for each mui Slide when the button is clicked. It seems like they don't want to cooperate and work together. Oddly enough, if you disable one of the slides, the other one starts working fine, but ...

Alternatives to getElementById in AngularJS

I am currently utilizing the jquery CircularSlider Plugin to implement 4 sliders on a single page. I have customized values for each slider and now I am looking to retrieve the value of each slider using an angularjs Directive. var intensity = $('#i ...

When the jQuery button is clicked, the execute function will run multiple times

I am attempting to create a button using jQuery that calls a JavaScript function, but I am facing an issue : Upon loading the page, the first click on mybutton does not elicit any response The second click results in the function being executed twice On ...

Generating multiple div elements within an AJAX iteration

Currently, I am retrieving data from the server side using AJAX. My goal is to populate data from a list of objects into divs but I am facing an issue where I cannot create the div while inside the foreach loop. $(document).ready(function () { var ...

Error message "Jquery smooth scrolling issue: Unable to retrieve property 'top' as it is not defined"

I'm currently working on a script for a back to top button that will be placed in the footer of my website. However, I'm running into an issue where I'm getting an error message saying "Cannot read property 'top' of undefined". Any ...

Strategies for resolving the module not found error: Unable to locate '@mui/icons-material/Adb'?

I installed material-ui core using the command below: npm i @material-ui/core However, when running my reactjs code afterwards, I encountered this error message: Module not found: Can't resolve '@mui/icons-material/Adb' Can someone pleas ...

The rotation of Google Maps always returns to its default position when I open the map information window by clicking on it

I have successfully implemented a Google Map with tilt and heading functionality, allowing the map to rotate horizontally. However, I am facing an issue where clicking on a marker resets the map back to its original position. You can view the map by follo ...

Having trouble with Material-UI Textfield losing focus after re-rendering? Need a solution?

I am currently utilizing Material-ui Textfield to display a repeatable array object: const [sections, setSections] = useState([ { Title: "Introduction", Text: "" }, { Title: "Relationship", ...