html 首先提取,然后显示PDF在单独的浏览器没有弹出警告

lokaqttq  于 2023-05-15  发布在  其他
关注(0)|答案(1)|浏览(176)

我目前正面临以下问题:
单击一个按钮就可以从API中获取base64编码的PDF数据,随后该文档将显示在另一个浏览器选项卡中。
我使用React和Redux商店作为前端框架。
以下是基本设置:
我们有一个按钮。点击后,会触发对后端API的GET请求:

<button onClick={() => fetchDocument(id)}/>

为API提供文档ID,它成功返回PDF的base64编码数据以及媒体类型(application/pdf)。相关数据(base64字符串和应用程序类型)存储在redux存储对象中,我们称之为pdfDocData
然后,我使用React的useEffect钩子来检查特定的redux store变量是否已经更改,以及它是否已定义。如果是这样,我开始打开新标签,如下所示:

useEffeft(() => {
  if (reduxStore.pdfDocData) {
    const docData = reduxStore.pdfDocData;
    const blob = base64ToBlob((docData.base64Data), docData.type);
    const url = URL.createObjectURL(blob);
    const pdfWindow = window.open();
    pdfWindow.location.href = url;
  }
}, [reduxStore.pdfDocData]);

因此,单击按钮后,首先,从后端API获取数据,然后将响应存储在redux存储中。通过订阅该商店并通过useEffect“收听”更新,我在一个新的浏览器选项卡中初始化显示PDF。
当我用谷歌Chrome浏览器尝试时,这绝对很好用。
然而,例如Firefox和Safari,在这里更严格。它们基本上将此视为弹出窗口,并且默认情况下阻止打开新窗口的尝试。
我尝试了很多东西,以使所有的浏览器只是显示在一个新的选项卡的PDF毫不犹豫。我尝试了window.open()中的参数,例如:

window.open(url, "_blank", "norefferer, noopener")

然后我尝试使用<iframe><embed>标记,但都不起作用。问题总是一样的。
据我所知,这基本上是因为按钮点击事件和新浏览器标签页的打开不是,我怎么能说...,“直接相关”。我们总是首先有抓取过程,redux商店更新,这反过来又触发了新浏览器标签的打开。
我目前没有看到任何机会或方式,我可以实现我的目标,即获取pdf数据,然后在一个新的标签打开它没有中断。它实际上听起来像一个标准的任务,获取pdf数据并随后显示它。但我不知道如何才能避免某些浏览器阻止弹出窗口。
我会非常高兴任何提示或建议,我如何可以克服这个问题。
先谢谢你了。

xdnvmnnf

xdnvmnnf1#

其实找到了答案。
诀窍是在单击按钮后立即打开一个新的空白窗口。

const pdfWindow = window.open('about:blank');

然后在try-catch块中执行所有的异步数据获取操作。收到响应后,创建一个URL并将其转发到已经打开的窗口,如下所示:

try {
        
            const res: any = await fetch("https://www.giveMeSomePdfData.org/now");

            const blob = base64ToBlob(res.payload);  /// just some function to make a blob out of base64 data
            const url = URL.createObjectURL(blob);
            pdfWindow.location.href = url; // and here, we finally forward the data to the new window
            pdfWindow.focus();
        } catch (e) {
            pdfWindow.close();
            const error = new Error(e)
            console.log(error)
        }

相关问题