質問

I'm sending a binary file via multipart POST request in the following way:

var xhr = new XMLHttpRequest();
body = '--' + boundary + '\r\n'
             + 'Content-Disposition: form-data; name="file"; '
             + 'filename="temp.bin"\r\n'
             + 'Content-type: application/octet-stream\r\n\r\n'
             + encryptedFileContent + '\r\n'
             + '--' + boundary + '--';
xhr.open("POST", "http://localhost:999/some/path", true);
xhr.setRequestHeader("Content-type", "multipart/form-data; boundary="+boundary);
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200)
        console.log("File uploaded!");
}
xhr.send(body);

I'm sending it within a chrome packaged app, and the reason I'm sending the file in this way is because initially the file is read from local filesystem via FileReader, and then it gets encrypted before being submitted. encryptedFileContent is built in the following way:

var reader = new FileReader();
reader.onload = function(e) {
     var plainArray = Array.apply([], new Int8Array(e.target.result));
     var encryptedArray = encrypt(plainArray);
     var encryptedFileContent="";
     for (var i=0; i<encryptedArray.length; i++) { 
          encryptedFileContent+=String.fromCharCode(encryptedArray[i]) 
     }
}
reader.readAsArrayBuffer(file);

Debugging, I can see that the encryptedArray contains the following values:

[ 70, -21, -15, ... ]

On the server side, when the array is read, I would expect to see the same data, but instead I see:

[ -17, -66, -112, ... ]

Looks like the way I build the payload for the binary file is incorrect. Is String.fromCharCode the issue?

役に立ちましたか?

解決

The reason the byte array received on the server was different is that the payload is converted to unicode and encoded to utf-8. In order to send data without any conversion, you should send data as binary, as described here:

https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest?redirectlocale=en-US&redirectslug=DOM%2FXMLHttpRequest%2FUsing_XMLHttpRequest#Submitting_forms_and_uploading_files

if (!XMLHttpRequest.prototype.sendAsBinary) {
    XMLHttpRequest.prototype.sendAsBinary = function(sData) {
        var nBytes = sData.length, ui8Data = new Uint8Array(nBytes);
        for (var nIdx = 0; nIdx < nBytes; nIdx++) {
            ui8Data[nIdx] = sData.charCodeAt(nIdx) & 0xff;
        }
        /* send as ArrayBufferView...: */
        this.send(ui8Data);
        /* ...or as ArrayBuffer (legacy)...: this.send(ui8Data.buffer); */
    };
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top