首页 > 解决方案 > InvalidCharacterError:无法在“Window”PDF 文件上执行“atob”

问题描述

我正在尝试使用角度从端点获取 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:无法在“窗口”上执行“atob”:要解码的字符串未正确编码。错误:无法在“窗口”上执行“atob”:要解码的字符串未正确编码。在 ZoneDelegate 的 article-list.component.ts:103 的 articleListComponent.push../src/app/article-list/article-list.component.ts.ArticleListComponent.base64ToArrayBuffer (article-list.component.ts:130)。 push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invoke (zone.js:391) 在 Object.onInvoke (core.js:17299) ...

标签: angulartypescript

解决方案


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

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

带有模拟 base64 的示例工作片段

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'
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.5.5/rxjs.umd.js"></script>


推荐阅读