iOS“Web App"的 localStorage 与 Mobile Safari 不同 [英] iOS 'Web App' has different localStorage than Mobile Safari

查看:29
本文介绍了iOS“Web App"的 localStorage 与 Mobile Safari 不同的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带有元标记的 iPad 网络应用程序:

I have a webapp for iPad with the meta tag:

<meta name="apple-mobile-web-app-capable" content="yes">

当我从主页打开应用程序(支持 web 应用程序的版本)或在 Mobile Safari 中输入地址时,localStorage 的内容是不同的.我已通过打印 location.href 确认地址相同.

When I open up the app from the homepage (web-app-capable version) or type in the address in Mobile Safari the contents of localStorage are different. I have confirmed that the addresses are identical by printing location.href.

在使用 Mobile Safari 时对 localStorage 所做的所有更改都反映在支持 web 应用的版本中,但在支持 web 应用的版本中所做的更改不会反映在 Mobile Safari 版本中.

All changes made to localStorage while using Mobile safari are reflected in the web-app-capable version, but changes made in the web-app-capable version are not reflected in the Mobile Safari version.

域是相同的,localStorage 应该是相同的.世界正在发生什么?这可以解决吗?

The domains are identical, localStorage should be identical. What in the world is going on? Can this be fixed?

更新 - 解决方案:按照已接受答案中的建议 #2(强制用户处于全屏模式),我添加了以下代码:

Update - Solution: Following suggestion #2 from the accepted answer (forcing the user to be in fullscreen mode) I added this bit of code:

if(("standalone" in window.navigator) && !window.navigator.standalone)
    window.location = "instructions.html";

因此,如果您使用的是支持独立模式的浏览器,并且您未处于独立模式,请重定向到一个页面 (instructions.html),该页面向用户展示如何将应用添加到主屏幕.

So, if you are using a browser that supports standalone mode, and you are not in standalone mode, redirect to a page (instructions.html) which shows the user how to add the app to the home screen.

感谢大家的投入!

推荐答案

总结:

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

Safari and full-screen web apps (a.k.a. web-app-capable) have separate in-memory write-through caches of the localStorage data. Each time the full-screen app becomes active, it reloads the localStorage from disk (allowing it see Safari's changes). However, when Safari becomes active, it doesn't reload the localStorage data from disk, so it won't see changes made in the full-screen app unless you kill Safari and restart it.

完整说明:

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

There are only two hard problems in Computer Science:

  1. 缓存失效
  2. 命名事物
  3. 一对一错误

localStorage 中的错误行为是问题 #1 的结果.原因如下:

The buggy behavior in localStorage is a result of problem #1. Here's why:

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

When the iOS browser engine loads, it reads the data for localStorage from disk and caches it in memory. Then each time you read data (e.g. getItem), the data is read from memory, not from disk; and when writing (e.g. setItem) the data is written to memory, and then (asynchronously) flushed to disk. Since localStorage is synchronous, this implementation is a totally reasonable. If it went to disk for all reads and writes, your javascript would be blocked on every read/write to perform expensive disk IO.

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

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

When you add the fact that FSWA completely reloads (which means the localStorage data is reloaded from disk) each time they become the active application, you get the behavior that you are seeing.

这是幕后花絮...

  1. 用户进行更改,将数据写入 Safari 中的 localStorage
  2. Safari 将数据写入 Safari 的内存中的 localStorage 缓存
  3. Safari 将 localStorage 数据从缓存刷新到磁盘
  4. 用户离开 safari 并启动 FSWA
  5. FSWA 从磁盘加载 localStorage 数据并将其读取到内存缓存中
  6. 用户在 Safari 中看到已更改的数据(在第 1 步中)
  7. 用户更改将数据写入 localStorage 的 FSWA
  8. FSWA 将数据写入其 localStorage 缓存(Safari 的缓存未更新)
  9. FSWA 将其 localStorage 缓存数据刷新到磁盘
  10. 用户切换回 Safari
  11. Safari 已经在运行,它不会从磁盘重新加载 localStorage 数据
  12. Safari 从其现有的内存缓存中读取旧数据
  13. 用户看不到第 7 步中所做的更改

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

To prove this, you can kill Safari between step #4 and step #10. Then when you relaunch Safari in step #11, it will reload the localStorage from disk and you will see the data written by the FSWA.

这篇关于iOS“Web App"的 localStorage 与 Mobile Safari 不同的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆