javascript 存储临时客户端数据
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/27798248/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Storing temporary client side data
提问by Jo E.
I need to store client side data temporarily. The data will be trashed on refresh or redirect. What is the best way to store the data?
我需要临时存储客户端数据。数据将在刷新或重定向时被丢弃。存储数据的最佳方式是什么?
using javascript by putting the data inside a variable
使用 javascript 通过将数据放入一个 variable
var data = {
a:"longstring",
b:"longstring",
c:"longstring",
}
or
或者
putting the data inside html elements (as data-attribute
inside div tags)
将数据放在 html 元素中(如data-attribute
在 div 标签中)
<ul>
<li data-duri="longstring"></li>
<li data-duri="longstring"></li>
<li data-duri="longstring"></li>
</ul>
The amount of data to temporarily store could get a lot because the data I need to store are image dataUri's and a user that does not refresh for the whole day could stack up maybe 500+ images with a size of 50kb-3mb. (I am unsure if that much data could crash the app because of too much memory consumption. . please correct me if I am wrong.)
临时存储的数据量可能会很多,因为我需要存储的数据是图像 dataUri,而一整天不刷新的用户可能会堆叠 500 多张大小为 50kb-3mb 的图像。(我不确定这么多数据是否会因为内存消耗过多而导致应用程序崩溃。如果我错了,请纠正我。)
What do you guys suggest is the most efficient way to keep the data?
你们建议什么是保存数据的最有效方法?
采纳答案by Adam
I'd recommend storing in JavaScript and only updating the DOM when you actually want to display the image assuming all the image are not stored at the same time. Also note the browser will also store the image in its own memory when it is in the DOM.
我建议存储在 JavaScript 中,并且仅在您实际想要显示图像时才更新 DOM,假设所有图像不是同时存储的。另请注意,当图像在 DOM 中时,浏览器也会将图像存储在自己的内存中。
Update: As comments have been added to the OP I believe you need to go back to customer requirements and design - caching 500 x 3MB images is unworkable - consider thumbnails etc? This answer only focuses on optimal client side caching if you really need to go that way...
更新:由于评论已添加到 OP,我相信您需要回到客户要求和设计 - 缓存 500 x 3MB 图像是行不通的 - 考虑缩略图等?如果您确实需要这样做,则此答案仅侧重于最佳客户端缓存...
Data URI efficiency
数据URI效率
Data URIsuse base64which adds an overhead of around 33% representing binary data in ASCII.
数据 URI使用base64,这增加了大约 33% 的开销,表示 ASCII 中的二进制数据。
Although base64 is required to update the DOM the overhead can be avoided by storing the data as binary strings and encoding and decoding using atob() and btoa()functions - as long as you drop references to the original data allowing it to be garbage collected.
尽管需要使用 base64 来更新 DOM,但可以通过将数据存储为二进制字符串并使用atob() 和 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));
String memory efficiency
字符串内存效率
How much RAM does each character in ECMAScript/JavaScript string consume?suggests they take 2 bytes per character - although this is still could be browser dependent.
ECMAScript/JavaScript 字符串中的每个字符消耗多少 RAM?建议他们每个字符占用 2 个字节 - 尽管这仍然可能取决于浏览器。
This could be avoided by using ArrayBufferfor 1-to-1 byte storage.
这可以通过使用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));
Disclaimer: Note all this add a lot of complexity and I'd only recommend such optimisation if you actually find a performance problem.
免责声明:请注意,所有这些都会增加很多复杂性,如果您确实发现了性能问题,我只会推荐这种优化。
Alternative storage
替代存储
Instead of using browser memory
而不是使用浏览器内存
- local storage- limited, typically 10MB, certainly won't allow - 500 x 3MB without specific browser configuration.
- Filesystem API- not yet widely supported, but ideal solution - can create temp files to offload to disk.
回答by japrescott
if you really want to loose the data on a refresh, just use a javascript hash/object var storage={}
and you have a key->value store. If you would like to keep the data during the duration of the user visiting the page (until he closes the browser window), you could use sessionStorage
or to persist the data undefinetly (or until the user deletes it), use localStorage
or webSQL
如果您真的想在刷新时丢失数据,只需使用 javascript 哈希/对象,var storage={}
并且您有一个键-> 值存储。如果您想在用户访问页面期间保留数据(直到他关闭浏览器窗口),您可以使用sessionStorage
或永久保存数据(或直到用户删除它),使用localStorage
或webSQL
putting data into the DOM (as a data-attribute or hidden fields etc) is not a good idea as the process for javascript to go into the DOM and pull that information out is very expensive (crossing borders between the javascript- and the DOM-world (the website structure) doesn't come cheap)
将数据放入 DOM(作为数据属性或隐藏字段等)并不是一个好主意,因为 javascript 进入 DOM 并提取该信息的过程非常昂贵(跨越 javascript- 和 DOM- 之间的边界)世界(网站结构)并不便宜)
回答by The_Black_Smurf
Using Javascript variable is the best way to store you temp data. You may consider to storing your data inside a DOM attribute only if the data is related to a specific DOM element.
使用 Javascript 变量是存储临时数据的最佳方式。仅当数据与特定 DOM 元素相关时,您才可以考虑将数据存储在 DOM 属性中。
About the performance, storing your data directly in a javascript variable will probably be faster since storing data in a DOM element would also involve javascript in addition to the DOM modifications. If the data isn't related to an existing DOM element, you'll also have to create a new element to store that value and make sure it isn't visible to the user.
关于性能,将数据直接存储在 javascript 变量中可能会更快,因为除了 DOM 修改之外,将数据存储在 DOM 元素中还涉及 javascript。如果数据与现有 DOM 元素无关,您还必须创建一个新元素来存储该值并确保它对用户不可见。
回答by corse32
The OP mentions a requirement for the data to be forcibly transient i.e. (if possible) unable to be saved locally on the client - at least that is how I read it.
OP 提到要求数据必须是强制瞬态的,即(如果可能)无法在客户端本地保存 - 至少我是这样阅读的。
If this type of data privacy is a firm requirement for an application, there are multiple considerations when dealing with a browser environment, I am unsure whether the images in question are to be displayed as imagesto the user, or where in relation to the client the source data of the images is coming from. If the data is coming into the browser over the network, you might do well (or better than the alternative, at least) to use a socket or other raw data connection rather than HTTP requests, and consider something like a "sentinel" value in the stream of bytes, to indicate boundaries of image data.
如果这种类型的数据隐私是应用程序的严格要求,那么在处理浏览器环境时有多种考虑,我不确定有问题的图像是作为图像显示给用户,还是与客户端相关的位置图像的源数据来自。如果数据通过网络进入浏览器,您可能会做得很好(或至少比替代方案更好)使用套接字或其他原始数据连接而不是 HTTP 请求,并考虑在字节流,用于指示图像数据的边界。
Once you have the bytes coming in, you could, I believe, (or soon will be able to) pass the data via a generator function into a typedArray via the iterator protocol, see: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array
一旦你有字节进来,我相信你可以(或很快将能够)通过生成器函数将数据通过迭代器协议传递到 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]
And then perhaps integrate those arrays as private members of some class you use to manage their lifecycle? see:
然后也许将这些数组集成为您用来管理其生命周期的某个类的私有成员?看:
https://www.nczonline.net/blog/2014/01/21/private-instance-members-with-weakmaps-in-javascript/
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;
}());
I think you should be able to manage the size / wait problem to some extent with the generator method of creating the byte arrays as well, perhaps check for sane lengths, time passed on this iterator, etc.
我认为您应该能够在某种程度上使用创建字节数组的生成器方法来管理大小/等待问题,也许检查合理的长度、在此迭代器上传递的时间等。
A general set of ideas more than an answer, and none of which are my own authorship, but this seems to be appropriate to the question.
一组普遍的想法不仅仅是一个答案,其中没有一个是我自己的作者,但这似乎适合这个问题。
回答by Kailas
There are various ways to do this, depending upon your requirement:
有多种方法可以做到这一点,具体取决于您的要求:
1) We can make use of constant variables, create a file Constants.js and can be used to store data as
1)我们可以利用常量变量,创建一个文件Constants.js,可以用来存储数据
"KEY_NAME" : "someval"
eg:
var data = {
a:"longstring",
b:"longstring",
c:"longstring",
}
CLIENT_DATA = data;
Careful:This data will be lost if you refresh the screen, as all the variables memory is just released out.
注意:如果刷新屏幕,这些数据将丢失,因为所有变量内存都刚刚释放出来。
2) Make use of cookieStore, using:document.cookie = some val;
For reference :http://www.w3schools.com/js/tryit.asp?filename=tryjs_cookie_usernameCareful:Cookie store data has an expiry period also has a data storage capacity https://stackoverflow.com/a/2096803/1904479.
Use:Consistent long time storage. But wont be recommended to store huge 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) Using Local Storage:
3) 使用本地存储:
localStorage.setItem("key","value");
localStorage.getItem("key");
Caution:This can be used to store value as key value pairs, as strings, you will not be able to store json arrays without stringify()
them.
Reference:http://www.w3schools.com/html/tryit.asp?filename=tryhtml5_webstorage_local
注意:这可用于将值存储为键值对,如字符串,如果没有stringify()
它们,您将无法存储 json 数组。
参考:http : //www.w3schools.com/html/tryit.asp? filename= tryhtml5_webstorage_local
4) Option is to write the data into a file
Reference:Writing a json object to a text file in javascript
4) 选项是将数据写入文件
参考:Writing a json object to a text file in javascript
回答by Dane
Why not used @Html.Hidden ?
为什么不使用 @Html.Hidden ?
@Html.Hidden("hId", ViewData["name"], new { @id = "hId" })