title: File corruption/encoding issue after download and saving via ajax function
body: <p>I have a Rails 6 controller function that generates a Excel file. This is a GET request/form submit of 3 criteria, 2 dates and a mode variable. Nothing fancy at all. This works with small amounts of data in the returned Excel file, but when larger volumes are required it takes ages and the browser times out. I've modified this, client side, with jQuery to override the timeout and submit the serialized form as a GET request in order to grab the search criteria used. The search, generation of the Excel file and response seems OK. Its the resulting document that appears corrupt when using the ajax mechanism below.</p>
  <p>Of course I originally had issues with saving the file as its an ajax request but found a few references that showed a trick to use <code>window.URL.createObjectURL()</code> along with an anchor and automated click to get around this. However, the resulting file is not what was originally generated and sent.</p>
  <p><strong>Server side controller function</strong></p>
  <p>This uses the gem axlsx to generate the Excel file</p>
  <pre><code>def download
    @download_without_times = true
    set_time_range_and_get_data(params[:mode])
    render &quot;bulk_download&quot; 
  end
  </code></pre>
  <p>Even using <code>send_file(@filename, options = {})</code> works if I call it directly but the same issue exists when saving via the ajax/createObjectURL method.</p>
  <p><strong>Server side view contents</strong></p>
  <p>I would suggest this is irrelevant but just in case</p>
  <pre><code>wb = xlsx_package.workbook
  wb.add_worksheet(name: &quot;Sensor Data&quot;) do |sheet_sensor_data|
  sheet_sensor_data.add_row [
                           &quot;datahog_id&quot;, 
                           &quot;sensor_data_id&quot;, 
                           &quot;collected_at&quot;,
                           &quot;inserted_at&quot;,
                           &quot;datahog_name&quot;,
                           &quot;sensor_description&quot;, 
                           &quot;sensor_type&quot;,
                           &quot;sensor_units&quot;,
                           &quot;value&quot;,
                           &quot;datahog_raw&quot;
                          ]
  if !@sensor_data.blank?
    @sensor_data.each do | sensor_data |
    
    sheet_sensor_data.add_row [
                                sensor_data.datahog_sensor.datahog_id, 
                                sensor_data.datahog_sensor_id, 
                                sensor_data.datahog_timestamp.strftime(DATETIME),
                                sensor_data.created_at.strftime(DATETIME),
                                sensor_data.datahog_sensor.datahog.name,
                                sensor_data.datahog_sensor.display_label,
                                sensor_data.datahog_sensor.sensor_type,
                                sensor_data.datahog_sensor.display_units,
                                sensor_data.value,
                                sensor_data.datahog_raw
                              ]
      end
    end
  end
  </code></pre>
  <p><strong>Client side Ajax function</strong></p>
  <p>Submits the serialized form and on success tries to save the returned 'data' as a file. Its just that he file appears to have been turned into garbage. So, I'm missing some kind of conversion or something.</p>
  <pre><code>$.ajax({
  url:'/download_table_data.xlsx',
  timeout: 0, 
  type:'GET',
  responseType: &quot;blob&quot;,
  data:$(this).serialize(),
  success:function(data, textStatus, jqXHR ){
    
    // How you download a file by ajax
    var fileName = 'download_table_data.xlsx';
    const objectURL = window.URL.createObjectURL(new Blob([data], {type: &quot;application/vnd.openxmlformats-officedocument.spreadsheetml.sheet&quot;}))
  
    var link= document.createElement('a');
    link.href=objectURL;
    link.download=fileName;
    link.click();
    
  },
  error: function (xhr, status) {
    toastr.error(&quot;Error getting data: &quot; + xhr.responseText);
    $('#download_data_form').show();
  },
  complete: function (xhr, status) {
    intervals.push(setInterval(get_live_table_data, refresh_timer));
    $('#notify_of_activity').hide();
    $('#download_data_form').show();
  }
  });
  </code></pre>
  <p>If I use a Hex viewer to compare the working version with the garbage the browser is saving, its obvious there's an issue as follows:-</p>
  <p><a href="https://i.stack.imgur.com/Igkym.png" rel="nofollow noreferrer">Valid Excel file </a></p>
  <p><a href="https://i.stack.imgur.com/mAkO5.png" rel="nofollow noreferrer">Garbage saved by the client</a></p>
  <p>NOTE: Loads of EF BF BD which, I think, is the UTF-8 sequence of bytes for U+FFFD, which is the Unicode code point replacement character. Someone with a <a href="https://stackoverflow.com/questions/47134243/why-excel-file-from-net-core-web-api-is-corrupt">very similar issue</a> was told he was probably decoding and encoding and introducing the issue. If I am, then I'm not sure where or how to fix it.</p>
  <p><strong>Request and response headers</strong></p>
  <p><a href="https://i.stack.imgur.com/spUq0.png" rel="nofollow noreferrer">The request/response headers</a></p>
  <p>If anyone can point me in the right direction it would be most appreciated.</p>