【问题标题】:InvalidCharacterError: Failed to execute 'atob' on 'Window' PDF fileInvalidCharacterError:无法在“Window”PDF 文件上执行“atob”
【发布时间】:2020-05-22 00:30:26
【问题描述】:

我正在尝试使用 angular 从端点获取 PDF 文件

showPdf(rowData: Article) {

  let promise = new Promise((resolve, reject) => {
    let apiURL = this.apiUrl + "/api/articles/get/" + rowData.id;
    this.http.get(apiURL)
      .toPromise()
      .then(
        res => { // Success

          this.results = String(res);
          const bytes = this.results;
          var arrBuffer = this.base64ToArrayBuffer(bytes);
          var file = new Blob([arrBuffer], { type: "application/pdf" });
          const fileName = 'report_' + rowData.id + '.pdf';
          if (window.navigator && window.navigator.msSaveOrOpenBlob) {
            window.navigator.msSaveOrOpenBlob(file, fileName); // For IE browser
          }
          const linkElement = document.createElement('a');
          const url = URL.createObjectURL(file);
          linkElement.setAttribute('href', url);
          linkElement.setAttribute('download', fileName);
          const clickEvent = new MouseEvent('click', {
            'view': window,
            'bubbles': true,
            'cancelable': false
          });
          linkElement.dispatchEvent(clickEvent);
      resolve();
      },
      msg => { // Error
      reject(msg);
      }
    );
});

}

base64ToArrayBuffer(data) {
  var binaryString = window.atob(data);
  var binaryLen = binaryString.length;
  var bytes = new Uint8Array(binaryLen);
  for (var i = 0; i < binaryLen; i++) {
      var ascii = binaryString.charCodeAt(i);
      bytes[i] = ascii;
  }
  return bytes;
};

当我调用 showPdf 函数时出现此错误:无法在 'Window' 上执行 'atob'

错误错误:未捕获(承诺中):InvalidCharacterError:失败 在'Window'上执行'atob':要解码的字符串不是 正确编码。 错误:无法在“窗口”上执行“atob”:要解码的字符串未正确编码。 在文章ListComponent.push../src/app/article-list/article-list.component.ts.ArticleListComponent.base64ToArrayBuffer (article-list.component.ts:130) 在 article-list.component.ts:103 在 ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invoke (zone.js:391) 在 Object.onInvoke (core.js:17299) ...

【问题讨论】:

    标签: angular typescript


    【解决方案1】:

    确保您提供的是有效的 base64 字符串

    例如,当您提供给atob dataUri: data:application/octet-stream;base64,... 时,您可能会收到此错误

    使用模拟 base64 的 sn-p 示例

    const that = {
      apiUrl: '',
      http: {
        get: () => rxjs.from(
          fetch("https://cors-anywhere.herokuapp.com/https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf")
          .then(response => response.blob())
          .then(blob => blobtoBase64(blob)).then(dataUri => {
            const [meta, data] = dataUri.split("base64,")
            return data;
          }))
      },
      results: null,
      base64ToArrayBuffer
    }
    
    function blobtoBase64(blob) {
      return new Promise((resolve, reject) => {
        const reader = new FileReader();
        reader.readAsDataURL(blob);
        reader.onloadend = function() {
          const base64data = reader.result;
          resolve(base64data);
        }
      });
    }
    
    async function showPdf(rowData) {
      let apiURL = that.apiUrl + "/api/articles/get/" + rowData.id;
    
      const res = await that.http.get(apiURL)
        .toPromise()
    
      that.results = res;
      const bytes = that.results;
    
      const arrBuffer = that.base64ToArrayBuffer(bytes);
      const file = new Blob([arrBuffer], {
        type: "application/pdf"
      });
      const fileName = 'report_' + rowData.id + '.pdf';
      if (window.navigator && window.navigator.msSaveOrOpenBlob) {
        window.navigator.msSaveOrOpenBlob(file, fileName); // For IE browser
      }
      const linkElement = document.createElement('a');
      const url = URL.createObjectURL(file);
      linkElement.setAttribute('href', url);
      linkElement.setAttribute('download', fileName);
      const clickEvent = new MouseEvent('click', {
        'view': window,
        'bubbles': true,
        'cancelable': false
      });
      linkElement.dispatchEvent(clickEvent);
    
    
    }
    
    function base64ToArrayBuffer(data) {
      const binaryString = window.atob(data);
      const binaryLen = binaryString.length;
      const bytes = new Uint8Array(binaryLen);
      for (let i = 0; i < binaryLen; i++) {
        const ascii = binaryString.charCodeAt(i);
        bytes[i] = ascii;
      }
      return bytes;
    };
    
    showPdf({
      id: '1'
    });
    &lt;script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.5.5/rxjs.umd.js"&gt;&lt;/script&gt;

    【讨论】:

    • 你是对的,后端没有正确发送 base 64 格式。感谢 Jozef 的有益回复
    猜你喜欢
    • 2014-04-29
    • 2021-12-17
    • 2020-09-15
    • 1970-01-01
    • 2021-03-25
    • 1970-01-01
    • 2022-11-06
    • 2019-01-07
    • 1970-01-01
    相关资源
    最近更新 更多