首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >cookie在浏览器中是原子读/写的吗?

cookie在浏览器中是原子读/写的吗?
EN

Stack Overflow用户
提问于 2013-01-14 14:17:12
回答 3查看 1.9K关注 0票数 17

我正在尝试实现一个符合我需要的交叉表互斥锁。我找到了一个实现here。这看起来很有前途。基本上,它实现了具有创建互斥锁的原子读/写需求的Leslie Lamport's algorithm

但是,它依赖于localStorage提供原子读/写。这在除Chrome之外的大多数浏览器中都工作得很好。

所以我的问题是,我可以使用cookie读/写来代替吗?cookie读/写在所有主流浏览器(IE,Chrome,Safari,Firefox)中都是原子的吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-02-13 17:14:24

cookies和localStorage都不提供原子事务。

我想你可能误解了这篇博文,它并没有说他的实现不能在Chrome上工作,它不依赖于localStorage提供原子读/写。他说,在Chrome中,正常的localStorage访问更加不稳定。我认为这与Chrome对每个标签使用单独的进程有关,而大多数其他浏览器倾向于对所有标签使用单个进程。他的代码在localStorage之上实现了一个锁定系统,该系统应该可以防止内容被覆盖。

另一种解决方案是使用IndexedDB。IndexedDB 确实提供了原子事务。作为一种新的标准,它不像localStorage那样支持很多浏览器,但在火狐、Chrome和IE10的最新版本中确实有很好的支持。

票数 7
EN

Stack Overflow用户

发布于 2013-02-13 15:19:46

不是的。即使浏览器可能在cookie上实现了读写锁,它也不能保护您免受在读和后续写之间发生的更改的影响。通过查看javascript API for cookies可以很容易地看到这一点,那里没有互斥功能……

票数 0
EN

Stack Overflow用户

发布于 2016-01-23 04:22:21

我今天使用localStorage遇到了这个并发问题(两年后..)

场景:浏览器(如Chrome)的多个标签页具有相同的脚本代码,基本上同时执行(由SignalR调用)。代码对localStorage进行读写操作。由于选项卡在不同的进程中运行,但共同访问共享的本地存储,因此读取和写入会导致未定义的结果,因为这里缺少锁定机制。在我的例子中,我希望确保只有一个选项卡可以与本地存储一起工作,而不是所有选项卡。

我尝试了上面问题中提到的Benjamin Dumke-von der Ehe的锁定机制,但得到了不想要的结果。所以我决定使用我自己的实验代码:

localStorage锁:

代码语言:javascript
复制
Object.getPrototypeOf(localStorage).lockRndId = new Date().getTime() + '.' + Math.random();
Object.getPrototypeOf(localStorage).lock = function (lockName, maxHold, callback) {
    var that = this;
    var value = this.getItem(lockName);
    var start = new Date().getTime();    
    var wait = setInterval(function() {
        if ((value == null) || (parseInt(value.split('_')[1]) + maxHold < start)) {
            that.setItem(lockName, that.lockRndId + '_' + start);
            setTimeout(function () {
                if (that.getItem(lockName) == (that.lockRndId + '_' + start)) {
                    clearInterval(wait);
                    try { callback(); }
                    catch (e) { throw 'exeption in user callback'; }
                    finally { localStorage.removeItem(lockName); }
                }
            }, 100);
        }        
    }, 200);        
};

使用:

localStorage.lock(lockName,maxHold,callback);

  • lockName -锁的全局范围唯一名称- string
  • maxHold -保护脚本的最长时间(以毫秒为单位)- integer
  • callback -包含受保护脚本的函数

示例:“仅在一个选项卡中播放声音”

代码语言:javascript
复制
//var msgSound = new Audio('/sounds/message.mp3');

localStorage.lock('lock1', 5000, function(){

    // only one of the tabs / browser processes gets here at a time
    console.log('lock aquired:' + new Date().getTime());

    // work here with local storage using getItem, setItem

    // e.g. only one of the tabs is supposed to play a sound and only if none played it within 3 seconds        
    var tm = new Date().getTime();
    if ((localStorage.lastMsgBeep == null)||(localStorage.lastMsgBeep <tm-3000)) {
       localStorage.lastMsgBeep = tm;
       //msgSound.play();                       
       console.log('beep');                        
    }  
});
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14314065

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档