0
votes

I am trying to send an image file to a backend server using a PUT request.

HTML:

<input type="file" name="myFile" id="profilePicInput">

Javacript:

const profileInput = document.getElementById('profilePicInput');
profileInput.addEventListener("change", handleFiles, false);

function handleFiles(){

    const formData = profileInput.files[0];

    $.ajax({
        url: '../uploadImage',    //my servlet url
        type: 'PUT',
        processData: false,
        contentType: false,
        data: {
            data: formData
        }, 
        success: function () {
            console.log("profile pic updated!");
        }
    });
}

The problem I'm facing is, in my backend code, I'm receiving data that has a content-type of 'text/plain;charset=UTF-8', but what i need is 'multipart/form-data'.

I've tried two things that didn't work:

  1. Using HTML forms

    <form id="profilePicForm" action="javascript:handleFiles()" method="post" enctype="multipart/form-data">
        <input type="file" name="myFile" id="profilePicInput">
    </form>
    

    Javascript:

    const profileInput = document.getElementById('profilePicInput');
    profileInput.addEventListener("change", submitForm, false);
    
    function submitForm(){
       document.getElementById("profilePicForm").submit();
    }
    

    But still the content-type in the request header says 'text/plain;charset=UTF-8' in my PUT request.

  2. Using FormData

    function handleFiles(){
    
        const blobFile = profileInput.files[0];
        let formData = new FormData();
        formData.append("fileToUpload", blobFile);
    
    
        $.ajax({
            url: '../uploadImage',    //my servlet url
            type: 'PUT',
            processData: false,
            contentType: false,
            data: {
                data: formData
            }, 
            success: function () {
                console.log("profile pic updated!");
            }
        });
    }
    

    Same problem. The content-type in the request header still says 'text/plain;charset=UTF-8' in my PUT request.

So my question is: how do you send a file with content-type=multipart/form-data through a PUT request?


UPDATE:

Solution:

HTML:

<input type="file" name="myFile" id="profilePicInput">

Javascript:

const profileInput = document.getElementById('profilePicInput');
profileInput.addEventListener("change", handleFiles, false);

function handleFiles(){

    let formData = new FormData();
    formData.append("fileToUpload", profileInput.files[0]);

    const xhr = new XMLHttpRequest();
    xhr.open('PUT', '../uploadImage');
    xhr.onload = () => {
        console.log("profile updated");
    };
    xhr.send(formData);

}
2
Where did you see type: 'PUT'? That would be method: 'put', then if you do a PUT, why don't you send directly the File (using XHR that would be var xhr = new XMLHttpRequest(); xhr.open('PUT', your_url); xhr.onload = callback; xhr.send(input.files[0]); - Kaiido
This really helped, thanks! I used XHR like you recommended, coupled with HTML forms, and it worked! I didn't encounter the multipart boundary error which I have been struggling with. Thanks again! - Sharon
@Kaiido — method and alias are aliases for each other in current jQuery. The value is case insensitive. - Quentin
@Quentin my bad, didn't saw the type in the docs... But I didn't meant to imply it was case sensitive anyhow though. - Kaiido

2 Answers

1
votes

See MDN on Uploading and Downloading Files.

If you want to PUT a file, then you just need to put the file and not wrap it in a multipart/form-data container.

Do not use FormData which is designed to pulling in all the data from a form and not just sending a single file.

const fileToUpload = profileInput.files[0]);
const xhr = new XMLHttpRequest();
xhr.open('PUT', '../uploadImage');
xhr.onload = () => {
    console.log("profile updated");
};
xhr.setRequestHeader("Content-Type", fileToUpload.type);
xhr.send(fileToUpload);
-1
votes

Take a look at the documentation: https://api.jquery.com/jquery.ajax/

It states that:

contentType: false,

will not send a content type, I would suggest this means the server recieving is then defaulting. Why not set the type here?

contentType: "multipart/form-data",