skip to Main Content

Okay so I have a correctly, base64-encoded png image, that I convert into a Blob as such:

const match = imgBase64String.match(/^data:image/(w+);base64,/);

if (!match) {

    throw new Error("Failed to decode base64-string.");

}

const imageSuffix = match[1];
const base64StringWithoutPrefix = imgBase64String.replace(
    /^data:image/w+;base64,/,
    ''
);
const imgAsBinaryString = atob(base64StringWithoutPrefix);

const blob = new Blob(
    [imgAsBinaryString],
    {type: `image/${imageSuffix}`}
);

I then append this data into a FormData instance, together with an additional key-value pair, like so:

const formDataPayload = new FormData();
formDataPayload.append(
    'img',
    blob,
    `img.${imageSuffix}`
);

formDayaPayload.append(
    'key',
    'value'
);

I then submit the instance using:

fetch(
    'https://example.org/my-endpoint',
    {
        method : 'POST',
        mode   : 'same-origin',
        cache  : 'no-cache',
        body: formDataPayload
    }
);

The dev tools show that the request is sent correctly as multipart/form-data request, with the according boundary, and the type property of the blob is correctly image/png. The Content-Type of the img property of the multipart/form-data payload is also image/png in the dev tools when inspecting the sent request. The problem is that the receiving server always still detects the upload img file as having the type application/octet-stream.

How can I assure that the MIME-type the server perceives is indeed image/png?

2

Answers


  1. Chosen as BEST ANSWER

    After seeing this, I found a working solution if I convert the base64-string to a BLOB and then in turn that BLOB into a File instance.

    With the risk coming with fetching dataURLs in your applications mentioned in the comments of the linked question, I came across this to generate the BLOB from your base64-string without relying on fetch in a way which in the end leads to the proper mime-type recognition on the server-side.


  2. To ensure the server correctly recognizes the MIME type of your uploaded file, you should convert the base64 string to a Uint8Array before creating the Blob.

    function base64ToUint8Array(base64) {
        var binaryString = atob(base64);
        var bytes = new Uint8Array(binaryString.length);
        for (var i = 0; i < binaryString.length; i++) {
            bytes[i] = binaryString.charCodeAt(i);
        }
        return bytes;
    }
    
    const match = imgBase64String.match(/^data:image/(w+);base64,/);
    
    if (!match) {
        throw new Error("Failed to decode base64-string.");
    }
    
    const imageSuffix = match[1];
    const base64StringWithoutPrefix = imgBase64String.replace(/^data:image/w+;base64,/, '');
    const uint8Array = base64ToUint8Array(base64StringWithoutPrefix);
    
    const blob = new Blob([uint8Array], {type: `image/${imageSuffix}`});
    
    const formDataPayload = new FormData();
    formDataPayload.append('img', blob, `img.${imageSuffix}`);
    formDataPayload.append('key', 'value');
    
    fetch('https://example.org/my-endpoint', {
        method : 'POST',
        mode   : 'same-origin',
        cache  : 'no-cache',
        body: formDataPayload
    });
    

    Hope this helps!

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search