iOS';网络应用程序&x27;与Mobile Safari具有不同的本地存储

iOS';网络应用程序&x27;与Mobile Safari具有不同的本地存储,ios,web-applications,local-storage,fullscreen,iphone-standalone-web-app,Ios,Web Applications,Local Storage,Fullscreen,Iphone Standalone Web App,我有一个带meta标签的iPad网络应用程序: <meta name="apple-mobile-web-app-capable" content="yes"> 因此,如果您使用的浏览器支持独立模式,而您没有处于独立模式,请重定向到一个页面(instructions.html),该页面向用户显示如何将应用程序添加到主屏幕 感谢大家的投入 假设您正确地保存了本地存储数据,并且如果我没有弄错的话,您所经历的是一个在web应用程序开发人员中常见的问题。Cookie、会话和本地存储在“we

我有一个带meta标签的iPad网络应用程序:

<meta name="apple-mobile-web-app-capable" content="yes">
因此,如果您使用的浏览器支持独立模式,而您没有处于独立模式,请重定向到一个页面(instructions.html),该页面向用户显示如何将应用程序添加到主屏幕


感谢大家的投入

假设您正确地保存了本地存储数据,并且如果我没有弄错的话,您所经历的是一个在web应用程序开发人员中常见的问题。Cookie、会话和本地存储在“web应用”(从主屏幕启动)中的存储方式似乎与通过mobile safari保存的数据不同

过去我对此做了一些相当彻底的测试,在我看来,没有足够好的解决办法。举一个例子,我和我的同事面临着一个类似的问题:在我们最近开发的一个web应用程序中,用户必须先登录,然后才能访问它的所有功能。如果一个人通过mobile safari登录,然后切换到该应用的下载版本,那么他可能会登录,但情况并非总是如此。用户通常必须再次登录,这表明cookie可能存储在不同的“数据库”中,具体取决于您选择如何或从何处启动应用程序

此外,正如卡尔文所说,它不仅仅是不同的数据库。通过主屏幕启动的应用程序打开速度似乎较慢,主屏幕应用程序在启动时总是重新加载,这表明没有多任务支持,等等。我的结论:启动下载的web应用程序的程序!=safari减去地址栏,因此不应被视为地址栏。

虽然苹果公司提供了一个不错的功能,但主屏幕web应用程序的性能并没有达到预期或人们希望的效果(就像在safari中打开的一样)。在您的情况下,假设您正确存储LS数据并尝试了不同的方法来解决特定问题,我建议您选择以下替代方法之一:

  • 改用mysql数据库从/到r/w
  • 强制用户在使用前下载应用程序(如中)
  • 不要鼓励用户下载该应用,并假设他们中的大多数人都会通过移动safari访问该应用
  • 接受数据可能不同的事实(根据应用程序的性质,这可能不是您的替代方案)
  • 按照我的方法,通过内置功能将您的web应用“转换”为本机应用。如果是这样,请看乔纳森·斯塔克的作品
    希望这至少有助于澄清其中的一部分。

    总结:

    Safari和全屏web应用程序(也称为支持web应用程序)具有单独的本地存储数据的内存直写缓存。每次全屏应用程序激活时,它都会从磁盘重新加载本地存储(允许它查看Safari的更改)。但是,当Safari处于活动状态时,它不会从磁盘重新加载localStorage数据,因此它不会看到在全屏应用程序中所做的更改,除非您杀死Safari并重新启动它

    完整解释:

    计算机科学中只有两个难题:

  • 缓存失效
  • 命名事物
  • 一个接一个的错误
  • localStorage中的错误行为是问题1的结果。原因如下:

    当iOS浏览器引擎加载时,它从磁盘读取本地存储的数据并将其缓存在内存中。然后每次读取数据时(例如,
    getItem
    ),数据都是从内存而不是从磁盘读取的;写入时(例如,
    setItem
    ),数据被写入内存,然后(异步)刷新到磁盘。由于localStorage是同步的,因此此实现是完全合理的。如果它进入磁盘进行所有读写操作,您的javascript将在每次读写时被阻止,以执行昂贵的磁盘IO

    问题在于,全屏web应用程序(我们称之为FSWA)使用iOS浏览器引擎的单独实例,尽管FSWA共享本地存储数据在磁盘上的相同位置,但它不与Safari共享本地存储数据的内存缓存。

    当您添加每次FSWA成为活动应用程序时都会完全重新加载(这意味着本地存储数据会从磁盘重新加载)的事实时,您就会看到所看到的行为

    这是幕后的故事

  • 用户进行更改,将数据写入Safari中的localStorage
  • Safari将数据写入Safari的内存中本地存储缓存
  • Safari将本地存储数据从缓存刷新到磁盘
  • 用户离开safari并启动FSWA
  • FSWA将本地存储数据从磁盘加载并读取到内存缓存中
  • 用户可以在Safari中看到已更改的数据(在步骤#1中)
  • 用户在将数据写入本地存储的FSWA中进行更改
  • FSWA将数据写入其本地存储缓存(Safari的缓存未更新)
  • FSWA将其本地存储缓存数据刷新到磁盘
  • 用户切换回Safari
  • Safari已经在运行,它不会从磁盘重新加载localStorage数据
  • Safari从其现有的内存缓存中读取旧数据
  • 用户看不到在步骤#7中所做的更改

  • 为了证明这一点,您可以在步骤4和步骤10之间切换。然后,当您在步骤11中重新启动Safari时,它将从磁盘重新加载localStorage,您将看到FSWA写入的数据。

    在iOS5中,我能够在同一个域上有两个全屏web应用程序,它们能够看到彼此的localStorage。这克服了全屏和Safari之间的差异


    然而,有了iOS6,我不得不将我的两个全屏web应用程序合并到一个应用程序中

    当你说web应用程序时,它是一个书签,作为应用程序保存在主屏幕上吗?或者它是一个应用程序,基本上是一个你已经包装和运行的网络视图
    if(("standalone" in window.navigator) && !window.navigator.standalone)
        window.location = "instructions.html";