在 React 的 IOS 15.1 上,通过 Safari 15.1 不支持的 JavaScript 打开 PDF 文件

Open a PDF file via JavaScript not supported in Safari 15.1 on IOS 15.1 in React

你好,我有一个带有这段代码的 React 应用程序

const getThePdfFileUrl = async (fileName: string) => {
    try {
      setDebug("debugging started...")
      if (fileName && fileName !== "" && !isDownloading) {
        setDebug("API call done...")

  
        // window.open(pdfFileUrl, "_blank");
        const a = document.createElement("a");
        a.setAttribute("href", "http://www.africau.edu/images/default/sample.pdf");
        a.setAttribute("target", "_blank");
        a.setAttribute("rel", "noopener noreferrer");
        a.click();
        setDebug("All okay...")
      }
      
    } catch (error) {
      setDebug("error comes...")
      setDebug(`error is...${JSON.stringify(error)}`)

      console.log("pdf error:-",error);
    }
  };

我管理一个组件状态来记录调试日志。我可以看到日志 “一切正常”。但这不是打开 link.

对于同一个网络应用程序,我添加了这段代码

  <a href="http://www.africau.edu/images/default/sample.pdf" target="_blank" rel="noopener noreferrer">some file</a>

这将毫无问题地打开 link。这在正常 html 中工作而不在 JavaScript 中工作有什么问题?

我看到了几种可能性:

  1. 如果元素不在文档中,某些浏览器将忽略 click() 调用(Firefox 肯定习惯了,不知道现在是否仍然如此)。有一次,某些浏览器(包括 Firefox)在添加元素后需要短暂的延迟,然后才允许点击调用。所以可能是 Safari 的行为方式相同。

  2. 您没有说明如何调用您的函数,但在几乎所有浏览器上,它都需要直接响应用户操作(如按钮单击)。 (通常也允许 setTimeout 安排直接响应用户操作,因为它可以追溯到用户操作。不过,该链条很容易被破坏。)

您可以这样称呼#1:

const a = document.createElement("a");
a.setAttribute("href", "http://www.africau.edu/images/default/sample.pdf");
a.setAttribute("target", "_blank");
a.setAttribute("rel", "noopener noreferrer");
document.body.appendChild(a); // ***
setTimeout(() => {            // ***
    a.click();
    setDebug("All okay...")
    document.body.removeChild(a); // *** You *might* need to put another `setTimeout` around this, but I don't think so
}, 70);                       // ***

您如何解决 #2 将取决于问题中未包含的信息。不过,基本上:确保调用该函数是为了直接响应用户操作。