title: fileReader.readAsBinaryString to upload files
body: <p>Trying to use fileReader.readAsBinaryString to upload a PNG file to the server via AJAX, stripped down code (fileObject is the object containing info on my file);</p>
  
  <pre><code>var fileReader = new FileReader();
  
  fileReader.onload = function(e) {
      var xmlHttpRequest = new XMLHttpRequest();
      //Some AJAX-y stuff - callbacks, handlers etc.
      xmlHttpRequest.open("POST", '/pushfile', true);
      var dashes = '--';
      var boundary = 'aperturephotoupload';
      var crlf = "\r\n";
  
      //Post with the correct MIME type (If the OS can identify one)
      if ( fileObject.type == '' ){
          filetype = 'application/octet-stream';
      } else {
          filetype = fileObject.type;
      }
  
      //Build a HTTP request to post the file
      var data = dashes + boundary + crlf + "Content-Disposition: form-data;" + "name=\"file\";" + "filename=\"" + unescape(encodeURIComponent(fileObject.name)) + "\"" + crlf + "Content-Type: " + filetype + crlf + crlf + e.target.result + crlf + dashes + boundary + dashes;
  
      xmlHttpRequest.setRequestHeader("Content-Type", "multipart/form-data;boundary=" + boundary);
  
      //Send the binary data
      xmlHttpRequest.send(data);
  }
  
  fileReader.readAsBinaryString(fileObject);
  </code></pre>
  
  <p>Examining the first few lines of a file before upload (using VI) gives me</p>
  
  <p><img src="https://i.stack.imgur.com/cSULu.png" alt="enter image description here"></p>
  
  <p>The same file after upload shows</p>
  
  <p><img src="https://i.stack.imgur.com/lPjoG.png" alt="enter image description here"></p>
  
  <p>So it looks like a formatting/encoding issue somewhere, I tried using a simple UTF8 encode function on the raw binary data</p>
  
  <pre><code>    function utf8encode(string) {
          string = string.replace(/\r\n/g,"\n");
          var utftext = "";
  
          for (var n = 0; n &lt; string.length; n++) {
  
              var c = string.charCodeAt(n);
  
              if (c &lt; 128) {
                  utftext += String.fromCharCode(c);
              }
              else if((c &gt; 127) &amp;&amp; (c &lt; 2048)) {
                  utftext += String.fromCharCode((c &gt;&gt; 6) | 192);
                  utftext += String.fromCharCode((c &amp; 63) | 128);
              }
              else {
                  utftext += String.fromCharCode((c &gt;&gt; 12) | 224);
                  utftext += String.fromCharCode(((c &gt;&gt; 6) &amp; 63) | 128);
                  utftext += String.fromCharCode((c &amp; 63) | 128);
              }
  
          }
  
          return utftext;
      )
  </code></pre>
  
  <p>Then in the original code</p>
  
  <pre><code>//Build a HTTP request to post the file
  var data = dashes + boundary + crlf + "Content-Disposition: form-data;" + "name=\"file\";" + "filename=\"" + unescape(encodeURIComponent(file.file.name)) + "\"" + crlf + "Content-Type: " + filetype + crlf + crlf + utf8encode(e.target.result) + crlf + dashes + boundary + dashes;
  </code></pre>
  
  <p>which gives me the output of</p>
  
  <p><img src="https://i.stack.imgur.com/J5pva.png" alt="enter image description here"></p>
  
  <p>Still not what the raw file was =(</p>
  
  <p>How do I encode/load/process the file to avoid the encoding issues, so the file being received in the HTTP request is the same as the file before it was uploaded.</p>
  
  <p>Some other possibly useful information, if instead of using fileReader.readAsBinaryString() I use fileObject.getAsBinary() to get the binary data, it works fine. But getAsBinary only works in Firefox. I've been testing this in Firefox and Chrome, both on Mac, getting the same result in both. The backend uploads are being handled by the <a href="http://www.grid.net.ru/nginx/upload.en.html" rel="noreferrer">NGINX Upload Module</a>, again running on Mac. The server and client are on the same machine. The same thing is happening with any file I try to upload, I just chose PNG because it was the most obvious example.</p>