HTML5应用缓存不能与POST请求一起工作
我正在开发一个Web应用程序,并且我经历了为我的初始登录页面启用HTML5应用缓存的必要步骤。我的目标是缓存所有的图像,CSS和JS,以提高性能,同时在线浏览,我不打算在脱机浏览。HTML5应用缓存不能与POST请求一起工作
我的初始页面由一个只有一个输入标签用于输入用户名的登录表单和一个提交按钮来将信息作为POST请求处理。提交的信息在服务器上验证,如果出现问题,则会再次显示初始页面(这是我目前正在测试的场景)
我正在使用浏览器的开发人员工具进行调试,一切工作正常初始请求(通过在浏览器中输入URL来获得GET请求);清单文件中列出的资源已被正确缓存,但是当POST请求的结果再次显示相同的页面时,我注意到之前缓存的所有元素(图像,css,js)都将从服务器再次获取。
这是否意味着HTML5应用缓存仅适用于GET请求?
根据http://www.whatwg.org/specs/web-apps/current-work/multipage/offline.html#the-application-cache-selection-algorithm在我看来,只有GET被允许。
在现代浏览器(支持脱机HTML)中,GET请求可能足够长以提供必要的数据以获取所需的数据,并且POST请求不应该用于幂等性请求(非幂 - 改变)。因此,如果应用程序是离线有用的数据类型,并且通知用户他们需要登录才能获取发送给他们的内容以完全脱机使用(而您可以使用离线事件通知他们他们还没有完成必要的过程)。
我有完全相同的问题,我写了POST ajax调用的包装。这个想法是,当你尝试开机自检时,它首先会向简单的ping.php发出一个GET请求,并且只有在成功后才会请求POST。
下面是它的外观中的骨干观点:
var BaseView = Backbone.View.extend({
ajax: function(options){
var that = this,
originalPost = null;
// defaults
options.type = options.type || 'POST';
options.dataType = options.dataType || 'json';
if(!options.forcePost && options.type.toUpperCase()==='POST'){
originalPost = {
url: options.url,
data: options.data
};
options.type = 'GET';
options.url = 'ping.php';
options.data = null;
}
// wrap success
var success = options.success;
options.success = function(resp){
if(resp && resp._noNetwork){
if(options.offline){
options.offline();
}else{
alert('No network connection');
}
return;
}
if(originalPost){
options.url = originalPost.url;
options.data = originalPost.data;
options.type = 'POST';
options.success = success;
options.forcePost = true;
that.ajax(options);
}else{
if(success){
success(resp);
}
}
};
$.ajax(options);
}
});
var MyView = BaseView.extend({
myMethod: function(){
this.ajax({
url: 'register.php',
type: 'POST',
data: {
'username': 'sample',
'email': '[email protected]'
},
success: function(){
alert('You registered :)')
},
offline: function(){
alert('Sorry, you can not register while offline :(');
}
});
}
});
有你的清单是这样的:
NETWORK:
*
FALLBACK:
ping.php no-network.json
register.php no-network.json
文件ping.php很简单,只要:
<?php die('{}') ?>
而no-network.json看起来像这样:
{"_noNetwork":true}
然后你去了,在任何POST之前,它将首先尝试GET ping.php并在离线状态下调用offline()。
希望这有助于;)