Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

XmlHttpRequest overrideMimeType for outgoing data

I want XmlHttpRequest to not touch (i.e. convert to UTF-8 or any other encoding) any of the characters it is sending and receiving to/from server.

For the characters received from the server, I know I can do XmlHttpRequest#overrideMimeType('text/plain; charset=x-user-defined') and the characters are left alone.

However, for the characters sent to the server via XmlHttpRequest#send call, I couldn't find a way to tell XmlHttpRequest to not touch those characters. I see that XmlHttpRequest encodes them into UTF-8 no matter what I tried. Is there a way to prevent this?

like image 791
Mete Atamel Avatar asked Nov 06 '22 01:11

Mete Atamel


1 Answers

I ran into a similar problem to upload audio grabbed from a microphone (via flash). Here is how I solved it (tested in FF 9 and chromium 15). The following js code takes a binary input as a string, and uploads it to the server without any alterations/encoding. Hopefully this can be of use to someone.

    var audioBytes = <the data you want sent untouched>
    var crlf = '\r\n';
    var body = '';
    var doubleDash = '--';
    var boundary = '12345678901234567890';

    var file = {
            name: "online-recording.wav",
            type: "audio/x-wav",
            size: audioBytes.length,
            recordedContent: audioBytes
    };

    var body = doubleDash + boundary + crlf +
            'Content-Disposition: form-data; name="file"; ' +
            'filename="' + unescape(encodeURIComponent(file.name)) + '"' + crlf +
            'Content-Type: ' + file.type + crlf + crlf +
            file.recordedContent + crlf +
            doubleDash + boundary + doubleDash + crlf;

    // copy binary content into a ByteArray structure, so that the browser doesn't mess up encoding
    var audioByteArray = new Uint8Array(body.length);

    for (var i=0; i< audioByteArray.length; i++) {
            audioByteArray[i] = body.charCodeAt(i);
    }

    // use an XMLHttpRequest to upload the file
    var xhr = new XMLHttpRequest();
    xhr.onreadystatechange = function() {
                    console.log(xhr.readyState);
    };
    xhr.open('post', url, true);
    xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');

    // setup AJAX event handlers here

    xhr.setRequestHeader('Content-Type', 'multipart/form-data; boundary=' + boundary);
    xhr.send(audioByteArray.buffer);

The trick is to build the request from an ArrayBuffer, which is seen as binary data, so the browser doesn't mess with it. Alternatively, if you only target firefox, you could use xhr.sendAsBinary() (from what I've read, it's not ported to any other browser, whereas the above code seems W3C compliant)

like image 185
Laurent S Avatar answered Nov 10 '22 21:11

Laurent S