【问题标题】:Issues storing JSON data in sessionStorage在 sessionStorage 中存储 JSON 数据的问题
【发布时间】:2017-10-15 09:00:07
【问题描述】:

我正在尝试利用 HTML5 sessionStorage 来保留以前从外部 API 检索到的一些数据,以便在以后再次调用时缓存数据,而不是建立连接来检索已经检索到的冗余数据会议。

function getItemWithTooltip(item_id, div_id) {
var xmlhttp2 = new XMLHttpRequest();
var url2 = "https://api.guildwars2.com/v2/items/"+item_id;

xmlhttp2.onreadystatechange=function() {if (xmlhttp2.readyState == 4 && xmlhttp2.status == 200) {parseItemTooltip(xmlhttp2.responseText);}};
xmlhttp2.open("GET", url2, true);
//xmlhttp2.send();

var item;

var cache_enabled = true;
// Cache results for quicker page loads
if (cache_enabled == true){
    if (Storage !== void(0)) {
        // Retrieve data (if stored)
        if (sessionStorage[String(item_id)]) {
            //item = JSON.parse(sessionStorage.getItem(String(item_id)));
            item = JSON.parse(sessionStorage[item_id.toString()]);
            //window.alert("sessionStorage: Retrieved");
            //alert(typeof (item));
            //alert(item);
        }
    }
}

if (item == null){
    xmlhttp2.send();
}

  function parseItemTooltip(response) {
    //var item = JSON.parse(response);

    if (item == null){
        // Store data
        if (cache_enabled == true){sessionStorage.setItem(item_id.toString(), JSON.stringify(response));}
        //sessionStorage.setItem(String(item_id), item);
        //if (cache_enabled == true){sessionStorage.setItem(String(item_id), response);}
        //window.alert("sessionStorage: Stored");
        item = JSON.parse(response);
    }
    //..More code here that was not relevant and removed to save space..
  }
}

【问题讨论】:

  • PS:它第一次工作,当它远程检索数据时,但是它无法使用从 sessionStorage 检索的数据工作。 :(
  • 有你的 json 样本要展示吗?
  • 您确定sessionStorage[String(item_id)] 确实有效吗?
  • 是的,那部分正在工作。
  • String(item_id) 或 item_id.toString() 似乎都可以正常工作。

标签: javascript json sessionstorage


【解决方案1】:

我认为这个问题与您在存储响应时JSON.stringify 的事实有关。响应已经是一个字符串,因此将对其进行“双重字符串化”,当您解析它时,您只会得到原始字符串。

您对响应文本同时执行JSON.stringifyJSON.parse。这对 JSON 没有意义,您应该只需要执行其中一项。如果您对字符串进行字符串化,它将变为“双字符串化”。如果你试图解析一个对象,你会得到错误,因为JSON.parse 需要一个字符串。

假设您的回复文本如下所示:

'{"property":"value"}'

这是一个字符串。现在,当你把它字符串化时,它会变成这样:

'"{\"property\":\"value\"}"'

当你解析它时,就像你从sessionStorage 获取它一样,你只会得到原始字符串。你必须再次解析它才能得到你想要的对象。

当您直接对响应文本进行解析时,您会正确获取对象:

{
  property: "value"
}

因此,您需要做的是将响应文本存储在sessionStorage 中而不对其进行字符串化。


您也只是在请求的状态更改处理程序中调用parseItemTooltip,因此当您获取缓存项时它永远不会被调用。查看您的完整代码,我可以看到您基本上完成了此函数中的所有操作,因此您需要在不执行请求时显式调用它。

【讨论】:

  • 我也尝试过使用 JSON.stringify 和 JSON.parse 的变体,以及不使用它们,因为数据已经是 JSON。
  • 改变这个:if (cache_enabled == true){sessionStorage.setItem(item_id.toString(), JSON.stringify(response));} 到这个:if (cache_enabled == true){sessionStorage .setItem(item_id.toString(), response);}
  • 我正在检索它:item = JSON.parse(sessionStorage[item_id.toString()]);
  • 还查看了您的实际代码,您对 parseItemTooltip 函数中的对象做了很多事情,但该函数仅在您执行实际 AJAX 请求时运行,当您从 @987654332 获取它时@你没有对@987654333做任何事情@
  • 我非常感谢您的回答,并感谢您尝试帮助我。 :D
【解决方案2】:

好吧,在我又检查了一个小时的代码之后,我终于找到了问题所在,而且这很简单,就像往常一样。

我的答案是把这两行颠倒过来:

    getItemWithTooltip(item.id, div_ID);
    document.getElementById("id01").innerHTML = out;

到这里:

    document.getElementById("id01").innerHTML = out;
    getItemWithTooltip(item.id, div_ID);

推理:它试图在创建 div 之前填充它。 以前没关系,因为是在等待远程服务器响应的时候填的, 但是现在将数据缓存到 sessionStorage 中,它被检索得如此之快,以至于顺序确实成为一个因素。 总是很好地注意进展的逻辑顺序。

感谢所有参与调试的人。非常感谢和赞赏! 快速的反应,和友好的人。为这个网站上的初学者打造了一段美好的时光。

【讨论】:

    猜你喜欢
    • 2017-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-24
    • 2017-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多