如何在不获取文件的情况下从后端获取文件JSON-parsed

How to get a file from the backend withou getting it JSON-parsed

我能够从我的 rails 后端获取一个 xlsx 文件,其中包含 GET-Request 到“/companies/export_xslx”,现在我面临着获取文件传递的问题JSON 解析器。对于每个请求,控制台都会显示“JSON.parse:JSON 数据的第 1 行第 1 列出现意外字符”。

这是我的设置:

//company model ...
exportXlsx: function() {
  const adapter = this.store.adapterFor('company');
  return adapter.exportXlsx();
}

//adapters/company.js
import DS from 'ember-data';
import TokenAuthorizerMixin from 'ember-simple-auth-token/mixins/token-authorizer';

export default DS.JSONAPIAdapter.extend(TokenAuthorizerMixin, {

  exportXlsx() {
    const url = 'companies/export_xlsx';
    return this.ajax(url, 'GET',
      { dataType: 'text',
         accepts: { xlsx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
       } });
  }
});

我将尝试更改默认接受 header 但请求发送时带有“接受:application/vnd.api+json”.

我已经用“ember-custom-actions”或“ember-cli-file-saver”尝试了不同的方法,它们都以JSON.parse...响应失败。

我找到了解决办法。我通过下载服务解决组件中的问题:

// components/companies-download.js
import Component from '@ember/component';
import { computed } from '@ember/object';
import { inject as service } from '@ember/service';

export default Component.extend({

  download: service(),

  actions: {

    downloadXlsx() {
      let url = `/companies/export_xlsx`;
      this.get('download').file(url);
    }

  }
});



// services/download.js
import Service from "@ember/service";
import { inject as service } from '@ember/service';

export default Service.extend({

  session: service(),

  file(url) {
    let xhr = new XMLHttpRequest();
    xhr.responseType = 'blob';
    xhr.onload = () => {
      let [, fileName] = /filename[^;=\n]*=((['"]).*?|[^;\n]*)/.exec(
        xhr.getResponseHeader("Content-Disposition")
      );
      let file = new File([xhr.response], decodeURIComponent(fileName));
      let link = document.createElement('a');
      link.style.display = 'none';
      link.href = URL.createObjectURL(file);
      link.download = file.name;
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
    };
    xhr.open('GET', url);
    xhr.setRequestHeader(
      'Authorization',
      'Bearer ' + this.get('session.data.authenticated.token')
    );
    xhr.send();
  }
});