我有一个带有元标记的iPad的webapp:
<meta name="apple-mobile-web-app-capable" content="yes">
当我从主页(支持网络应用程序的版本)打开应用程序或在Mobile Safari中输入地址时,localStorage的内容会有所不同。我已通过打印location.href确认地址相同。
使用移动版Safari时对localStorage所做的所有更改都反映在支持Web应用程序的版本中,但在支持Web应用程序的版本中所做的更改不会反映在Mobile Safari版本中。
域名相同,localStorage应该相同。世界上到底发生了什么?这可以修复吗?
更新 - 解决方案:根据接受的答案提示#2(强制用户处于全屏模式),我添加了以下代码:
if(("standalone" in window.navigator) && !window.navigator.standalone)
window.location = "instructions.html";
因此,如果您使用的浏览器支持独立模式,并且您不处于独立模式,请重定向到页面(instructions.html),该页面向用户显示如何将应用程序添加到主屏幕。
感谢大家的投入!
答案 0 :(得分:26)
<强>要点:强>
Safari和全屏网络应用程序(支持网络应用程序)具有localStorage数据的单独内存中直写高速缓存。每次全屏应用程序变为活动状态时,它都会从磁盘重新加载localStorage(允许它查看Safari的更改)。但是,当Safari变为活动状态时,它不会从磁盘重新加载localStorage数据,因此除非您杀死Safari并重新启动它,否则它不会在全屏应用程序中看到更改。
完整说明:
计算机科学中只有两个难题:
localStorage中的错误行为是问题#1的结果。原因如下:
当iOS浏览器引擎加载时,它会从磁盘读取localStorage的数据并将其缓存在内存中。然后每次读取数据(例如getItem
)时,数据都从内存中读取,而不是从磁盘读取;写入时(例如setItem
),数据被写入内存,然后(异步)刷新到磁盘。由于localStorage是同步的,因此这种实现是完全合理的。如果它进入磁盘进行所有读写操作,则每次读/写时都会阻止javascript执行昂贵的磁盘IO。
问题是全屏网络应用程序(让我们称之为FSWA)使用iOS浏览器引擎的单独实例,虽然FSWA在磁盘上为localStorage数据共享相同的位置,但它没有与Safari共享localStorage数据的内存缓存。
当您添加FSWA每次成为活动应用程序时完全重新加载(这意味着从磁盘重新加载localStorage数据)的事实时,您将获得您所看到的行为。
这是幕后的......
为证明这一点,您可以在步骤#4和步骤#10之间kill Safari。然后,当您在步骤#11中重新启动Safari时,它将从磁盘重新加载localStorage,您将看到FSWA写入的数据。
答案 1 :(得分:5)
在iOS5中,我能够在同一个域上拥有两个能够看到彼此的localStorage的全屏网络应用程序。这克服了全屏和Safari之间的差异。
然而,对于iOS6,我必须将我的两个全屏网络应用程序合并到一个应用程序。
答案 2 :(得分:3)
假设您正确保存本地存储数据,如果我没有弄错的话,您在网络应用开发者中遇到的有些常见问题。 Cookie,会话和本地存储似乎以不同方式存储在“网络应用”(从主屏幕启动)到通过移动版Safari保存的数据中。
我过去对此进行了一些相当彻底的测试,并且在我看来,没有足够好的解决方法。仅举几个例子,我和我的同事遇到了类似的问题:在我们最近开发的Web应用程序中,用户必须先登录才能访问其所有功能。如果通过移动safari登录然后切换到应用程序的下载版本,则需要登录,但情况并非总是如此。通常需要再次登录,建议cookie可以存储在不同的“数据库”中,具体取决于您选择启动应用程序的方式或位置。
此外,正如凯文所说,还有更多,而不仅仅是不同的数据库。通过主屏幕启动的应用似乎打开得更慢,主屏幕应用程序在启动时总是重新加载,表明没有多任务支持等。我的结论:程序启动下载的网络应用程序!= safari减去地址栏,因此不应该这样对待。
虽然Apple 是一个很好的功能,但是主屏幕网络应用程序并没有像预期的那样完美地运行(或者像在safari中打开一样)。在您的情况下,假设您存储LS数据正确并尝试了不同的方法来解决您的特定问题,我建议使用以下替代方法之一:
希望这有助于澄清至少部分内容。