在Safari上下载base64 pdf

时间:2019-01-21 03:25:45

标签: javascript pdf safari

我有一个POST调用,返回一个base64 PDF。当我调用此端点时,将其转换为Blob,然后下载。在Safari以外的所有浏览器中,该功能都可以正常工作。

openPdf = () => {

  const sendObj = {
    fakeValue: 'test'
  };

  axios.post('https://fakeendpoint.com/create-pdf', sendObj)                
    .then((res) => {
      const base64URL = res.data;
      const binary = atob(base64URL.replace(/\s/g, ''));
      const len = binary.length;
      const buffer = new ArrayBuffer(len);
      const view = new Uint8Array(buffer);

      for (let i = 0; i < len; i += 1) {
        view[i] = binary.charCodeAt(i);
      }

      // create the blob object with content-type "application/pdf"
      const blob = new Blob([view], { type: 'application/pdf' });
      const url = URL.createObjectURL(blob);

      const a = document.createElement('a');
      document.body.appendChild(a);
      a.style = 'display: none';
      a.href = url;
      a.download = 'Test.pdf';
      a.target = '_blank';
      a.click();
  });
}

如何在Safari中使用它?

2 个答案:

答案 0 :(得分:1)

似乎Safari没有遵循const{name,value} = event.target;标签的标准。我相信this previous SO post确定了根本原因。从链接答案中的评论中:

  

请注意,在Safari中指定目标属性似乎会覆盖下载属性(在Chrome,Firefox或Opera中似乎并非如此)。

尝试删除上面代码中的a,然后对其进行测试。它应该工作!

不幸的是,我不确定您如何在更改后的新标签页中打开它。

答案 1 :(得分:0)

根据我所做的测试-仅在PDF太大时才会发生。 (并且仅在移动Safari上) 我认为这与URL的长度有关。

删除fun showTimePicker(viewId: Int) { val cal = Calendar.getInstance() val timeSetListener = TimePickerDialog.OnTimeSetListener { timePicker, hour, minute -> cal.set(Calendar.HOUR_OF_DAY, hour) cal.set(Calendar.MINUTE, minute) findViewById<EditText>(viewId).setText(SimpleDateFormat("HH:mm").format(cal.time)) } TimePickerDialog(this, timeSetListener, cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE), true).show() } 的唯一缺点是,如果用户单击“后退”,将失去先前的页面状态。