我需要暂时存储客户端数据。数据将在刷新或重定向时被删除。存储数据的最佳方法是什么?
将数据放在variable
var data = {
a:"longstring",
b:"longstring",
c:"longstring",
}
或
将数据放在html元素中(如data-attribute
在div标签内)
<ul>
<li data-duri="longstring"></li>
<li data-duri="longstring"></li>
<li data-duri="longstring"></li>
</ul>
临时存储的数据量可能会大量增加,因为我需要存储的数据是图像数据,并且一天内不刷新的用户可能会堆叠500多个图像大小为50KB-3MB。 (由于内存消耗过多,我不确定是否有太多数据会导致应用程序崩溃。如果我错了,请纠正我。)
你们建议什么是最有效的数据保存方式?
答案 0 :(得分:2)
如果你真的想在刷新时丢失数据,只需使用javascript哈希/对象var storage={}
,你就有了一个key-&gt;值存储。如果您希望在用户访问页面期间保留数据(直到他关闭浏览器窗口),您可以使用sessionStorage
或不确定地保留数据(或直到用户删除它),使用localStorage
或webSQL
将数据放入DOM(作为数据属性或隐藏字段等)并不是一个好主意,因为javascript进入DOM并将信息拉出的过程非常昂贵(跨越javascript-和DOM世界(网站结构)并不便宜)
答案 1 :(得分:2)
我建议您在JavaScript中存储,只有在您想要显示图像时才更新DOM,假设所有图像不是同时存储的。另请注意,当浏览器位于DOM中时,浏览器还会将图像存储在自己的内存中。
更新:由于评论已添加到OP中,我认为您需要回到客户要求和设计 - 缓存500 x 3MB图像是行不通的 - 考虑缩略图等?这个答案只关注最佳的客户端缓存,如果你真的需要这样的话......
Data URIs使用base64会增加大约33%的开销,代表ASCII中的二进制数据。
虽然需要base64来更新DOM,但是通过将数据存储为二进制字符串以及使用atob() and btoa()函数进行编码和解码,可以避免开销 - 只要您删除对原始数据的引用,使其成为垃圾收集。
var dataAsBase64 = "iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==";
var dataAsBinary = atob(dataAsBase64);
console.log(dataAsBinary.length + " vs " + dataAsBase64.length);
// use it later
$('.foo').attr("src", "data:image/png;base64," + btoa(dataAsBinary));
How much RAM does each character in ECMAScript/JavaScript string consume?建议每个字符占用2个字节 - 尽管这仍然取决于浏览器。
使用ArrayBuffer进行1对1字节存储可以避免这种情况。
var arrayBuffer = new Uint8Array(dataAsBinary.length );
for (i = 0; i < dataAsBinary.length; i++) {
arrayBuffer[i] = dataAsBinary.charCodeAt(i);
}
// allow garbage collection
dataAsBase64 = undefined;
// use it later
dataAsBase64 = btoa(String.fromCharCode.apply(null, arrayBuffer));
$('.foo').attr("src", "data:image/png;base64," + btoa(dataAsBinary));
免责声明:请注意,所有这些都会增加很多复杂性,如果您确实发现了性能问题,我只建议进行此类优化。
而不是使用浏览器内存
答案 2 :(得分:1)
使用Javascript变量是存储临时数据的最佳方式。仅当数据与特定DOM元素相关时,您才可以考虑将数据存储在DOM属性中。
关于性能,将数据直接存储在javascript变量中可能会更快,因为在DOM元素中存储数据除了DOM修改之外还会涉及javascript。如果数据与现有DOM元素无关,那么您还必须创建一个新元素来存储该值,并确保它对用户不可见。
答案 3 :(得分:1)
OP提到要求数据强制过渡,即(如果可能的话)无法在本地保存在客户端上 - 至少我是这样阅读的。
如果此类数据隐私是对应用程序的严格要求,则在处理浏览器环境时需要考虑多个因素,我不确定相关图像是否显示为图像用户,或者与客户有关的图像的源数据来自何处。如果数据通过网络进入浏览器,您可能会(甚至比替代方案更好)使用套接字或其他原始数据连接而不是HTTP请求,并考虑像&#34; sentinel& #34;字节流中的值,用于指示图像数据的边界。
一旦你有了字节,你可以,我相信,(或很快就能够)通过生成器函数将数据通过迭代器协议传递到typedArray,参见:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array
// From an iterable
var iterable = function*(){ yield* [1,2,3]; }();
var uint8 = new Uint8Array(iterable);
// Uint8Array[1, 2, 3]
然后可能将这些数组集成为您用来管理其生命周期的某些类的私有成员?见:
https://www.nczonline.net/blog/2014/01/21/private-instance-members-with-weakmaps-in-javascript/
var Person = (function() {
var privateData = {},
privateId = 0;
function Person(name) {
Object.defineProperty(this, "_id", { value: privateId++ });
privateData[this._id] = {
name: name
};
}
Person.prototype.getName = function() {
return privateData[this._id].name;
};
return Person;
}());
我认为您应该能够在某种程度上使用创建字节数组的生成器方法来管理大小/等待问题,也许检查理智长度,在迭代器上传递的时间等等。
一般的一系列想法不仅仅是一个答案,而且都不是我自己的作者,但这似乎适合这个问题。
答案 4 :(得分:0)
为什么不使用@ Html.Hidden?
@Html.Hidden("hId", ViewData["name"], new { @id = "hId" })
答案 5 :(得分:0)
根据您的要求,有多种方法可以做到这一点:
1)我们可以利用常量变量,创建一个文件Constants.js,并可以用来存储数据
"KEY_NAME" : "someval"
eg:
var data = {
a:"longstring",
b:"longstring",
c:"longstring",
}
CLIENT_DATA = data;
小心:如果您刷新屏幕,此数据将会丢失,因为所有变量内存都已释放出来。
2)使用cookieStore,使用:
document.cookie = some val;
供参考:http://www.w3schools.com/js/tryit.asp?filename=tryjs_cookie_username
小心: Cookie存储数据的有效期也有数据存储容量https://stackoverflow.com/a/2096803/1904479。
使用:一致的长时间存储。但不建议存储大量数据
3)使用本地存储:
localStorage.setItem("key","value");
localStorage.getItem("key");
警告:这可用于将值存储为键值对,作为字符串,您将无法存储没有stringify()
它们的json数组。
的参考:强> http://www.w3schools.com/html/tryit.asp?filename=tryhtml5_webstorage_local
4)选项是将数据写入文件
参考: Writing a json object to a text file in javascript