我有一个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中使用它?
答案 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()
}
的唯一缺点是,如果用户单击“后退”,将失去先前的页面状态。