无法使用 jQuery.ajax() 从保存到 iOS 设备主屏幕的 Web 应用程序通过 AJAX 访问清单缓存文件
我正在制作一个网络应用程序。它加载的某些文件包含纯静态 .JSON 数据。我正在使用 jQuery.ajax() (jQuery 1.5.2) 和 dataType:'json' 和 cache:true。一切正常,所有文件均已加载。我还配置了缓存清单来缓存这些 JSON 文件(除了 css 、 js 和图像)。那里的一切也都运行良好 - 当用户访问我的网站时,我需要的所有文件都被正确缓存(我有 applicationCache 事件处理程序来确认一切正常)。我已经测试了 Google Chrome 中的所有内容,可以看到所有文件(包括 JSON 文件)都被缓存了。当我断开网络连接时,一切正常(jQuery ajax 调用自动获取缓存的 JSON 文件)。
现在我尝试在移动 Safari 上(在实际的 iPad 和 iPhone 模拟器上)对此进行测试。在 Safari 中,一切都按预期工作 - 页面被缓存,并且在网络断开连接的后续访问中,将使用缓存的文件。
但是,当我在 Safari 中使用“添加到主屏幕”将应用程序添加到主屏幕时,应用程序启动并且所有 .js、.css 和图像都能正常工作,但我的 Ajax 调用却不能!他们不访问缓存的 .json 文件。对于每个 Ajax 调用,XMLHttpRequest.status
为 0
,.statusText
为 error
,但 getAllResponseHeaders( )
显示与 Safari 中的功能应用程序相同(正确)的标头。
我不明白这一点。这是 jQuery 的 .ajax() 的限制/错误还是什么?任何帮助表示赞赏。
I'm making a webapp. Some of the files that it loads contain pure, static .JSON data. I am using jQuery.ajax() (jQuery 1.5.2) with dataType:'json' and cache:true. Everything works well and all files are loaded. I have also configured the cache manifest to cache these JSON files (in addition to css , js, and images). Everything works well there too - when a user visits my site all the files that I need are cached correctly (I have applicationCache event handlers that confirm all is well). I have tested everything in Google Chrome and I can see that all files (including the JSON ones) are cached. When I disconnect from the network, everything works (the jQuery ajax calls automagically fetch the cached JSON files).
Now I am trying to test this on mobile Safari (on actual iPad and the iPhone simulator). Everything works as expected when in Safari - the pages are cached and on subsequent visits with network disconnected, the cached files are used.
However, when I add the app to the Home Screen using "add to home screen" in Safari, the app starts up and all the .js, .css, and images work correctly, BUT my Ajax calls don't! They don't access the cached .json files. For each Ajax call the XMLHttpRequest.status
is 0
, .statusText
is error
, but getAllResponseHeaders()
shows the same (correct) headers as in the functional app in Safari.
I don't get this. Is this a limitation/bug in jQuery's .ajax() or what? Any help is appreciated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
好吧,我不想回答我自己的问题,但这是我所做的,以防其他人遇到这个问题:
显然,当尝试在离线模式下使用 $.ajax() 时,请求成功获取缓存文件,但它在 XHMLHttpRequest.status 上返回 0。阅读完此内容后,我发现当用户离线时甚至在请求本地文件时,都会返回状态代码 0。然而,成功的 GET 应该报告 200 到 300 之间的状态代码。也许 $.ajax() 检查 200-300 状态,否则请求被认为失败。
为了解决这个问题,我在
$.ajax()
请求的错误处理程序中添加了代码,该请求检查jqXHR.responseText.**length**
。我知道 JSON 文件中的正确字符数,因此如果jqXHR.responseText.length
与此已知值相同,我认为请求成功并继续加载文件。我唯一需要做的额外事情是在错误处理程序中添加 JSON.parse(jqXHR.responseText) ,因为状态代码 0 时不会解析数据。Well, I hate to have to answer my own question, but here is what I've done in case someone else runs into this problem:
Apparently, when trying to use $.ajax() in offline mode, the request successfully fetches the cached files, but it returns 0 on XHMLHttpRequest.status. Having read up on this, I have seen that a status code of 0 can be returned when the user is offline and even when requesting local files. However, a successful GET should report a status code between 200 and 300. Perhaps $.ajax() checks for a 200-300 status, otherwise the request is considered to have failed.
To get around this, I added code to my error handler for the
$.ajax()
request which checks thejqXHR.responseText.**length**
. I know the correct number of characters in my JSON files, so ifjqXHR.responseText.length
is the same as this known value, I consider the request a success and continue loading the files. The only extra thing I have to do is addJSON.parse(jqXHR.responseText)
in the error handler, because the data is not parsed on status code 0.解决这个问题的另一种方法(特别是如果您是 jQuery 粉丝)可能是使用 jQ Ajax 方法并强制不使用缓存:
显然,ajax 在离线时将无法加载服务器端数据,所以为什么不检查用户是否在线以及是否所以,继续获取数据:
Another way to go about this (especially if you're a jQuery fan) could be to use the jQ Ajax method and force no cache:
Obviously, ajax will fail to load server side data while offline so why not check if user's online and if so, go ahead and fetch data: