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

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

问题描述

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

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应用程序)具有单独的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在磁盘上共享localStorage数据的相同位置,但它没有共享与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将本地存储数据从缓存刷新到磁盘
  4. 用户离开野生动物园并启动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中所做的更改
  1. user makes a change that writes data to localStorage in Safari
  2. Safari writes data to Safari's in-memory localStorage cache
  3. Safari flushes localStorage data from cache to the disk
  4. user leaves safari and launches the FSWA
  5. FSWA loads and reads localStorage data from the disk into in-memory cache
  6. user sees the data that was changed (in step #1) in Safari
  7. user makes a change in the FSWA that writes data to localStorage
  8. FSWA writes data to its localStorage cache (Safari's cache is not updated)
  9. FSWA flushes its localStorage cache data to disk
  10. user switches back to Safari
  11. Safari was already running, and it does not reload the localStorage data from disk
  12. Safari reads the old data from its existing in-memory cache
  13. user does not see changes made in step #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'与Mobile Safari具有不同的localStorage的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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