Hello! The task is to upload the file (.exe) to the server, the selected file via
<input type="file" id="myfile"> I read like this (javascript):
var myfile=''; var input = document.getElementById('myfile'); input.onchange = function(evt){ var tgt = evt.target || window.event.srcElement, files = tgt.files; if (FileReader && files && files.length) { var fr = new FileReader(); fr.onload = function(){ myfile = fr.result; } fr.readAsDataURL(files[0]); } } Now I have a variable "myfile" of the form:
"data:application/msdownload;base64,0J/RgNC40LLQtdGCINC80LjRgCE= .... и т.д." Those. In base64 data there is a raw file ... When I try to upload a file to the server, everything is fine, BUT the encoding changes ... What am I doing wrong?
Uploading:
var fd = new FormData(); var b = new Blob([atob(decodeURIComponent((myfile).split(',')[1]))],{type: 'application/msdownload'}); fd.append('file', b, "myfile.exe"); var xhr = new XMLHttpRequest(); xhr.open("POST", "http://myserver/"); xhr.send(fd); Everything is good. The file is loading norms. But the downloaded file has a different encoding ... Ie it does not open. Because of this, the file size changes.
I tried to add a header of different encodings when sending, but to no avail.
xhr.setRequestHeader("Content-Type", "charset=windows-1251"); ............. xhr.setRequestHeader("Content-Type", "charset=utf-8"); и др...... What's wrong?
Please do not offer to download the file directly ... the file must be saved locally for a while ... and then unloaded.
Updated (to clarify the issue):
We have a Base64 line of the form:
0J/RgNC40LLQtdGCINC80LjRgCE= We know that it contains the contents of the executable file "SecretFile.exe". Obtained by the method described above.
When decoding with standard window.atob, the content is not equal to the source. How to get the source code from raw encoded in Base64, FileReader.
RESOLVED:
Attempts to transcode from encoding to encoding (as suggested by @Other UTF-8, 1251 ..., etc.) did not give any result. As well as attempts to read a file with different readAsText () methods, readAsBinaryString () ... however, the moment with Base64 was important, namely readAsDataURL (), which contains the same data as when reading by other methods, in a convenient form for storing them.
The solution, as often happens, is simple. Thank you @GoncharovAleksandr for answering my question on a big SO
As it turned out, the decoded string from Base64 is not directly the "image" of the file, but the characters for each byte of binary data that can be converted using the ( source ) function:
function b64toBlob(b64Data, contentType, sliceSize) { contentType = contentType || ''; sliceSize = sliceSize || 512; var byteCharacters = atob(b64Data); var byteArrays = []; for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) { var slice = byteCharacters.slice(offset, offset + sliceSize); var byteNumbers = new Array(slice.length); for (var i = 0; i < slice.length; i++) { byteNumbers[i] = slice.charCodeAt(i); } var byteArray = new Uint8Array(byteNumbers); byteArrays.push(byteArray); } var blob = new Blob(byteArrays, {type: contentType}); return blob; } Thanks to all! Maybe someone will come in handy.
FormDatafile from a text variable previously taken from input = file - Goncharov Alexander