【问题标题】:HTML5 history API to reduce server requests用于减少服务器请求的 HTML5 历史 API
【发布时间】:2013-08-10 06:09:40
【问题描述】:

我正在尝试开发一个搜索过滤器并利用 HTML5 历史 API 来减少发送到服务器的请求数量。如果用户选中一个复选框以应用某个过滤器,我会将该数据保存在历史状态中,这样当用户取消选中它时,我就可以从历史中加载数据,而不是从服务器再次获取它。

当用户选中或取消选中过滤器时,我正在更改窗口 URL 以匹配设置的过滤器,例如,如果用户尝试仅过滤某个类别的汽车品牌,我会更改 URL,例如“cars?filter-”品牌[]=1'。

但是当应用多个过滤器时,我无法确定是从服务器加载数据还是从历史记录加载数据。

目前我正在使用以下代码。

pushString variable is the new query string that will be created.
var back = [],forward = [];
if(back[back.length-1] === decodeURI(pushString)){   //check last back val against the next URL to be created
                back.pop();
                forward.push(currentLocation);
                history.back();
                return true;
            }else if(forward[forward.length-1] === decodeURI(pushString)){
                forward.pop();
                back.push(currentLocation);
                history.forward();
                return true;
            }else{
                back.push(currentLocation); //add current win location
            }

【问题讨论】:

    标签: browser-history html5-history


    【解决方案1】:

    您可以检查您的过滤器是否等效。

    比较对象

    这是一个简单的函数,它接受两个文件,并让您知道它们是否等效(注意:为简单起见,不是原型安全的)。

    function objEqual(a, b) {
      function toStr(o){
        var keys = [], values = [];
        for (k in o) {
          keys.push(k);
          values.push(o[k]);
        }
        keys.sort();
        values.sort();
        return JSON.stringify(keys) 
        + JSON.stringify(values);
      }
      return toStr(a) === toStr(b);
    }
    

    demo

    使用网址

    将 URL 的查询部分 (window.location.search) 传递给此函数。它会为您提供一个对象,您可以使用上述函数与另一个对象进行比较。

    function parseURL(url){
      var obj = {}, parts = url.split("&");
      for (var i=0, part; part = parts[i]; i++) {
        var x = part.split("="), k = x[0], v = x[1];
        obj[k] = v;
      }
      return obj;  
    }
    

    Demo

    历史 API 对象

    您可以使用 History API 存储对象。

    window.history.pushState(someObject, "", "someURL")
    

    您可以使用history.state 或在popState 处理程序中获取此对象。

    跟踪事物

    如果你从第一部分中拉出toStr 函数,你可以序列化当前的过滤器。然后,您可以将所有状态以及所有关联的数据存储在一个对象中。

    当你推送一个状态时,你可以更新你的全局 cache 对象。此代码应位于 AJAX 响应的处理程序中。

    var key = toStr(parseUrl(location.search));
    cache[key] = dataFromTheServer;
    

    然后抽象你的 AJAX 函数以首先检查缓存。

    function getFilterResults(filters, callback) {
        var cached = cache[toStr(filters)]
        if (cached != null) callback(cached);
        else doSomeAJAXStuff().then(callback);
    }
    

    您还可以使用 localstorage 进行更持久的缓存,但这需要更高级的代码和过期数据。

    【讨论】:

    • 你的第一点是使用一个函数来比较对象。我假设您建议将新状态与以前的状态进行比较。但要做到这一点,我将不得不从服务器重新获取数据,那么它就没有用了。目前,我将 URL 查询字符串部分保存在一个数组中,并将其与设置的新过滤器进行比较。但它不能正常工作。
    • 我添加了一些关于缓存数据的更多细节。
    • 您建议使用数组来保存数据,有没有办法使用历史状态对象来做到这一点。
    猜你喜欢
    • 2017-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-11
    • 1970-01-01
    • 2012-05-21
    • 1970-01-01
    • 2012-09-20
    相关资源
    最近更新 更多