简体   繁体   中英

Upload base64 image as a like file input with file name using AJAX

On server side I have spring MVC (JAVA) project which accepts multipart/form-data with MultipartFile

@RequestMapping(value = { "/uploadImg/**" }, method = RequestMethod.POST)
public void uploadImg(Model model, HttpServletRequest request,HttpServletResponse response,MultipartFile file ) 
{
     String originalFileName = file.getOriginalFilename();
     //some cases on based on file name and storing the file into the server
}

Previously, I am using <fomr> with <file> to upload the file. But now I have a image data in base64 format and wanted to upload using AJAX to same request mapping.

I come across this Upload base64 image with Ajax and plenty of such solutions. But all are uploading file data only but in my case I want to upload image with its data and name, as on server side some logic is written based on file name.

One option might be that, sending image data in parameter and file name in another parameter but I don't have access (or rather I cannot change) the server side code to do this.

So, using AJAX how can I upload base64 image data along with file name ?

I tested the following code with a PHP server. I don't have access to a Spring MVC server, but the JS code should be the same for both. The code is mostly based on this article: https://ourcodeworld.com/articles/read/322/how-to-convert-a-base64-image-into-a-image-file-and-upload-it-with-an-asynchronous-form-using-jquery

// I've shortend the base64 data to keep this answer short. See the linked article for the complete data
let ImageURL = "data:image/gif;base64,R0lGODlhPQBEAPeoAJosM....";

let block = ImageURL.split(";");
let contentType = block[0].split(":")[1];// In this case "image/gif"
let realData = block[1].split(",")[1];// In this case "R0lGODlhPQBEAPeoAJosM...."

let blob = b64toBlob(realData, contentType);

let formDataToUpload = new FormData();
formDataToUpload.append("image", blob, 'filename.gif'); // Here you can set the filename

$.ajax({
    url: '/upload.php',
    data: formDataToUpload,
    type: 'POST',
    contentType: false,
    processData: false
});

/**
 * Convert a base64 string in a Blob according to the data and contentType.
 *
 * @param b64Data {String} Pure base64 string without contentType
 * @param contentType {String} the content type of the file i.e (image/jpeg - image/png - text/plain)
 * @param sliceSize {int} SliceSize to process the byteCharacters
 * @see http://stackoverflow.com/questions/16245767/creating-a-blob-from-a-base64-string-in-javascript
 * @return Blob
 */
function b64toBlob(b64Data, contentType, sliceSize) {
    contentType = contentType || '';
    sliceSize = sliceSize || 512;

    let byteCharacters = atob(b64Data);
    let byteArrays = [];

    for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
        let slice = byteCharacters.slice(offset, offset + sliceSize);

        let byteNumbers = new Array(slice.length);

        for (let i = 0; i < slice.length; i++) {
            byteNumbers[i] = slice.charCodeAt(i);
        }

        let byteArray = new Uint8Array(byteNumbers);

        byteArrays.push(byteArray);
    }

    return new Blob(byteArrays, {type: contentType});
}

The best would be to change whatever generates this base64 version so it returns a Blob instead directly.

In the absence of such an option, you can still convert that base64 string into a Blob yourself. Once you have the Blob, you'll be able to post it to your server using either XMLHttpRequest or fetch , just like an html <form> thanks to the FormData API .

 // a 1x1px png image as base64 const b64 = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQImWNgYGBgAAAABQABh6FO1AAAAABJRU5ErkJggg=="; // set it to the "name" attribute of your <input type="file"> const the_name_of_your_previous_file_input = "file"; // set it to whatever filename you want const the_file_name = "pixel.png"; const blob = new Blob([base64ToArrayBuffer(b64)]); const form = new FormData(); form.append(the_name_of_your_previous_file_input, blob, the_file_name); console.log(...form); /* Uploads are commented since not working in StackSnippets // for modern browsers you can use fetch API fetch(YOUR_SERVER_URL, { method: "post", body: form } ); // or for older browsers const xhr = new XMLHttpRequest(); xhr.open("POST", YOUR_SERVER_URL); xhr.send(form); */ function base64ToArrayBuffer(base64) { const binary_str = atob(base64); const arr = new Uint8Array(base64.length); for(let i=0; i<arr.length; i++) { arr[i] = binary_str.charCodeAt(i); } return arr.buffer; }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM