我正在尝试根据服务器返回的响应生成 PDF 文件,并在新选项卡中打开该文件。它在所有浏览器的桌面上运行良好,但在苹果设备(iphone + ipad)的 safari 浏览器中出现问题。
这是代码片段:
if (responseType = base64 encoded string like JVBERi0xLjUKJeLjz9MKMSAwI....) {
const binaryString = window.atob(fileResponseData);
const bytes = new Uint8Array(binaryString.length);
const binaryToBlob = bytes.map((byte, i) => binaryString.charCodeAt(i));
const blob = new Blob([binaryToBlob], { type: 'application/pdf' });
this.downloadFile(blob, fileName);
} else {
// blob response like %PDF-1.7 %âãÏÓ5 0 obj....
const blob = new Blob([fileResponseData], { type: 'application/pdf' });
this.downloadFile(blob, fileName);
}
这就是我下载文件的方式
if (window.navigator && window.navigator.msSaveOrOpenBlob) {
window.navigator.msSaveOrOpenBlob(blob, fileName);
return;
}
const url = (window.URL || window.webkitURL).createObjectURL(blob);
window.open(url, '_blank');
我知道有关于这个主题的相关文章,但它们没有解决我的问题。事实上,我想出了上面的代码引用这些文章本身,但我仍然面临苹果设备的问题。一旦我单击按钮生成文件并在新选项卡中显示,苹果设备上没有任何反应,但其他设备工作正常。
我在使用 iOS 14.3 的 iPhone 6s+ 上也遇到同样的问题。看起来这是 iPhone/iPad 上 Safari 的一项功能,如果
window.open()
停留在某些不同的事件中(例如 onload
/onloadend
事件或 setTimeout
),则会阻止弹出窗口。您可以尝试将 window.open()
移动到另一个作用域或函数中以查看结果。对于我的问题,我通过创建一个隐藏的锚标记然后单击它来解决它:
mySmallDiv.innerHTML = '<a href="+'url'+" target="_blank" id="openPdf"> </a>';
document.getElementById("openPdf").click();
但 Safari 可能仍会阻止它,因此请相应地更改您的代码。
并且,不要忘记在超时后致电
URL.revokeObjectURL(url)
。此外,我认为如果浏览器是Chrome iOS,则需要使用
FileReader()
。
如果文件下载时间超过约 1 秒(997 毫秒),或者链接上的点击事件在用户点击后 1 秒后触发,我会遇到问题。您可以使用以下代码尝试一下:
点击后立即打开一个新窗口:
let myWindow = null
const winHtml = `<!DOCTYPE html><html><head><title>Downloading file, please wait</title><head><body><h1>Downloading file, please wait</h1></body></html>`
const winUrl = URL.createObjectURL(
new Blob([winHtml], { type: 'text/html' })
)
myWindow = window.open(winUrl, '_blank')
现在开始下载。下载完成后,将位置更改为 blob 中创建的对象 url:
const url = (window.URL || window.webkitURL).createObjectURL(blob)
if (myWindow === null)
window.open(url, '_blank')
else
myWindow.location.href = url
我在我的 React 应用程序中遇到了同样的问题,我想在新选项卡中打开 pdf blob url,iPad safari 不允许我这样做,但其他设备和浏览允许。当您想在 ipad safari 上的新选项卡中打开 pdf blob url 时,请参考以下代码:
// checks if the user agent string contains any of the keywords
"iPad", "iPhone", "iPod", "Macintosh", or "Mac". This covers most
Apple devices, including those running Safari.
if (/iPad|iPhone|iPod|Macintosh|Mac/.test(navigator.userAgent)) {
//assumes you have a doc object containing the PDF data. It
asynchronously saves the data to a byte array./
const bBody = await doc.save();
//This creates a Blob object representing the PDF data with the
correct mime type.
const blob = new Blob([bBody], { type: "application/pdf" });
const reader = new FileReader();
//callback function that gets called when the data is read
reader.onload = () => {
const iframe:any = document.getElementById("myIframe");
iframe.src = reader.result; // Non-null assertion
};
reader.readAsDataURL(blob);
}