HTML5 App Cache无法处理POST请求

时间:2010-10-20 17:23:11

标签: post html5 caching get

我正在开发一个Web应用程序,我已经完成了为我的初始登录页面启用HTML5 App Cache的必要步骤。我的目标是缓存所有图像,css和js以提高在线浏览时的性能,我不打算进行离线浏览。

我的初始页面包含一个登录表单,其中只有一个用于输入用户名的输入标记和一个提交按钮,用于将信息作为POST请求进行处理。提交的信息在服务器上验证,如果出现问题,将再次显示初始页面(这是我正在测试的场景)

我正在使用浏览器的开发人员工具进行调试,所有内容都适用于初始请求(通过在浏览器中键入URL来获取GET请求);清单文件中列出的资源已正确缓存,但是当POST请求再次显示同一页面时,我注意到之前缓存的所有元素(图像,css,js)都是从服务器再次获取的。

这是否意味着HTML5 App Cache仅适用于GET请求?

2 个答案:

答案 0 :(得分:4)

Per http://www.whatwg.org/specs/web-apps/current-work/multipage/offline.html#the-application-cache-selection-algorithm在我看来,只允许GET。

在现代浏览器(支持离线HTML)中,GET请求可能足够长,可以提供必要的数据来获取所需的数据,而POST请求不应该用于幂等的请求(非改变)。因此,应用程序应该被设计为允许GET请求,如果它是离线有用的数据类型,并通知用户他们需要登录才能将内容发送给他们以供完全脱机使用(并且您可以使用离线事件通知他们他们尚未完成必要的过程。)

答案 1 :(得分:1)

我遇到了完全相同的问题,我为POST ajax调用编写了一个包装器。这个想法是当你尝试POST时,它会首先向一个简单的ping.php发出GET请求,只有在成功的情况下才会请求POST。

以下是Backbone视图中的外观:

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': 'sample@sample.com'
            },
            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()。

希望这会有所帮助;)