移动 Safari 中的 React PWA 图像上传会中断应用程序吗?

Posted

技术标签:

【中文标题】移动 Safari 中的 React PWA 图像上传会中断应用程序吗?【英文标题】:React PWA Image Upload in Mobile Safari breaks application? 【发布时间】:2019-07-31 21:45:53 【问题描述】:

我们很惊讶我们在网上的任何地方都没有提到这个,所以我们在这里发帖希望我们能找到解决方案。

使用带有移动 safari 的 iPhone 是当我们遇到这个问题时,运行以下 2 个易于遵循的测试,一个有效,一个无效。

这是链接 https://pwa-react.netlify.com/

这是我们运行的 2 个测试(都在链接中列出),一个在不处于 PWA 模式时工作,另一个在 PWA 模式下失败。

测试 #1:完美运行(预期行为)

Visit https://pwa-react.netlify.com/ from iPhone in mobile safari
1. Make sure you have google drive on the phone but not logged in.
2. Click "Choose File". It will show you the list of options to choose from.
3. Click "Browse" to look for the photo.
4. Click "Cancel" and you're back here.
5. Click "Choose File" it will still show you the list of options to choose from.
   This works perfectly in mobile safari but NOT in PWA mode below.

测试 #2:不起作用(意外行为)(PWA)

Visit https://pwa-react.netlify.com/ from iPhone in mobile safari, hit the share
button, then add to home screen. This will add the PWA app on your phone. Open App.
1. Make sure you have google drive on the phone but not logged in.
2. Click "Choose File". It will show you the list of options to choose from.
3. Click "Browse" to look for the photo.
4. When it shows you the Google Drive logo with Sign In, double click the home 
   button, then go back to the PWA.
5. Click "Choose File" it will NOT show you the list of options to choose from. 
   This is now 100% broken.
   The ONLY way to fix it is to go to Settings>Safari>Clear History and Website Data (all the way down)
   How can we fix this so when the user hits "Choose File" it shows the list of 
   options to choose from in the PWA?

屏幕截图#1:这些是出现在Test #1中并停止出现在Test #2

中的选项

屏幕截图 #2: 此屏幕允许我们在 Test #1 中取消,但在 Test #2

中它会消失

知道如何让 Test #2 工作,方法是允许我们选择像 Screenshot #1 中的上传选项,而不会破坏应用程序并且不必去 safari设置清除历史记录和网站数据以使其再次运行?

PS - 这是存储库文件pwa-react/src/App.js

【问题讨论】:

【参考方案1】:

我们在 PWA 中面临几乎完全相同的问题,所以首先,我要感谢您帮助我们缩小原因。

在查看了 ios PWA 生命周期 (article here) 和几个小时的反复试验后,我找到了一个半可接受的解决方案。

我猜测当您在上传过程中离开应用程序(测试 #2)时会发生什么,是因为 iOS 如何处理未重置的 PWA 存在一些内部上下文,因此当您返回并尝试上传再次文件它认为上传对话框已经打开。

文章提到打开没有target=_blank的外部链接会导致PWA上下文被删除,所以当应用内浏览器关闭时,PWA页面会在独立窗口中重新加载。我认为这可能会重置“分离上传”上下文,它最终可以正常工作。

所以我创建了一个托管在另一个域上的页面,并在 PWA 中的上传按钮下方链接到它:

// not sure the target='_self' is necessary but not risking it
<a href='https://externalDomain.com/reset' target='_self'>
    Having Issues? Reset Upload
</a>

这工作得很好,减去一个问题。当您单击此链接时,它会打开应用内浏览器,但没有“完成”按钮或导航工具让用户知道如何退出。链接回 PWA 不起作用,因为 iOS 会检测到这一点并且不会重置应用上下文。我注意到的是,如果我从第一个外部页面导航到另一个页面(我最初只是在 google.com 上测试过),“完成”按钮会出现,从而清楚地知道如何退出。

有了这些知识,我猜您可能只需执行window.history.pushState 即可达到相同的效果,这很有效。我的最终解决方案如下。当用户从应用内浏览器按下完成时,它会导致整个应用重新加载,但在我看来,这比让它们重新添加到主屏幕要好得多。

const Reset: React.FC = props => 
    React.useEffect(() => 
        // Redirect any wayward users who find this page from outside the PWA
        if (!window.matchMedia('(display-mode: standalone)').matches) 
            navigate('/');
        
        // push an additional page into history
        const newUrl = `$window.location.href?reset`;
        window.history.pushState( path: newUrl , '', newUrl);
    , []);
    return (
        <Grid container>
            <ArrowUpIcon />
            <Typography variant='h5'>Press done above to return to App</Typography>
            <Typography variant='body1'>Sorry for the inconvenience!</Typography>
        </Grid>
    );
;

希望对您有所帮助!很想知道它是否适合您。

生产测试后编辑: 另一个重要的注意事项是,您的“重置”页面必须位于完全不同的域上才能正常工作。今天在生产中遇到了这个问题,因为我们的重置页面位于与 PWA 具有相同根目录的子域上,iOS 并未重置整个 PWA 生命周期。

总结

关键问题:

    在任何“文件上传”对话框(“拍照”、“照片库”或“浏览”)打开时离开 iOS PWA 会破坏 iOS PWA 生命周期。这种破坏使用户无法打开单击文件输入时出现任何“文件上传”对话框。 要解决此问题,必须完全重置 PWA 上下文。 似乎重置 PWA 上下文的唯一方法是重启手机、删除应用并重新添加到主屏幕,或者打开外部链接。 打开外部链接时,关闭 iOS PWA 嵌入式浏览器的“完成”按钮不会显示在初始页面上。用户必须导航到其他外部页面才能显示“完成”按钮。 外部链接在具有target="_blank" 时不会触发 PWA 上下文重置。

解决办法:

为了让用户能够再次上传文件,必须重置 PWA 上下文。最简单的方法(在我看来)是让他们打开一个外部链接。

    (在 PWA 中):向用户显示链接以修复未显示上传对话框的事实。链接目标必须是完全不相关的域(不是子域)并且必须有 target="_self"(问题 #5)。 (外部页面):一旦用户单击链接并打开外部页面,将无法离开页面(问题 #4)。要解决此问题,您可以使用history.pushState 模拟导航到其他页面。 (外部页面 - 奖励):为了让用户清楚地知道问题已经解决,请在左上角添加一个指向“完成”按钮的箭头(如我的屏幕截图所示)。

【讨论】:

感谢帕克分享解决方法!必须设置另一个与应用程序无关的页面才能正常工作似乎有点奇怪:/我们希望有另一个更好的解决方案来解决这个问题。我们发现在您的回答中遵循解决方案有点困难,您介意编号一些可实施的步骤(就像我们在问题中所做的那样)以使应用程序链接 (pwa-react.netlify.com) 工作吗? @Wonka 添加了更清晰的摘要,为混乱的答案道歉,但不幸的是这是一个混乱的问题!如果不清楚,外部页面仍会在“应用程序”中加载,并且没有可见的浏览器控件,因此还不错。这是一个 hacky 解决方法,但不幸的是,我们似乎无能为力。我什至去了this site,那里有 PWA 示例,并下载了一些我认为有文件上传功能的示例,看看他们是如何处理的。结果我设法破解了一堆 PWA :( Apple 缺乏文档也非常令人沮丧。 嗯...首先,感谢您提供分步解决方案,现在它更清晰了:) 所以它确实有效,这很好,但我看到的问题是当它重定向到&lt;a target="_self" 你看到的是一个完全不相关的 url,所以对于用户来说,它可能看起来很可疑(为什么这个应用程序将我发送到另一个 url?)。我不想浪费赏金,所以我会把它给你详细的解决方案,甚至首先提出这个解决方案,谢谢。在标题栏中点击链接后显示的其他网址是一个烦人的问题。 如果有一个我们都不知道的解决方案可能会以另一种方式解决,或者以其他 url 不显示或似乎的方式解决,我们将保持开放状态对用户来说很可疑。我可能必须创建一个新的赏金来吸引更多关注这个问题,并希望如果可能的话我们能得到另一个可行的解决方案,但如果没有其他方式 atm 也不会感到惊讶。再次感谢帕克! @Wonka 很抱歉现在才回到这个话题,创业世界中的事情往往会被遗忘:) 非常感谢,并同意保持开放 - 我希望有人能找到更好的解决方案.我们刚刚注册了另一个域(在我们的例子中是 orthly-app.com)来处理用户信任问题,但是,仍然不是很好。

以上是关于移动 Safari 中的 React PWA 图像上传会中断应用程序吗?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Safari iOS13+ 中从 PWA 下载图像

仅在 iOS 移动 Safari 中上传图像时出现错误的 CORS 失败

PWA:iOS 12 Safari 中的积极缓存

如何在 PWA (React) 中访问 ios 中的摄像头和耳机

首次访问 Nuxt 2.15.3、Tailwind 和 Pwa 模块时不加载 Safari 本地字体

PWA 与 Safari 网站有啥区别?