Я столкнулся с подобной проблемой при загрузке звука, снятого с микрофона (через вспышку).Вот как я это решил (проверено в FF 9 и Chromium 15).Следующий код js принимает двоичный ввод в виде строки и загружает его на сервер без каких-либо изменений / кодирования.Надеюсь, это кому-нибудь пригодится.
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);
Хитрость заключается в том, чтобы создать запрос из ArrayBuffer, который рассматривается как двоичные данные, поэтому браузер не связывается с ним.В качестве альтернативы, если вы ориентируетесь только на firefox, вы можете использовать xhr.sendAsBinary () (из того, что я прочитал, он не переносится ни на какой другой браузер, тогда как приведенный выше код кажется W3C-совместимым)