cookie是否在浏览器中读/写原子

时间:2013-01-14 06:17:12

标签: javascript html5 concurrency

我正在尝试为我的需求实现交叉表互斥锁。我找到了一个实现here。这似乎很有希望。基本上,它实现了Leslie Lamport's algorithm,需要原子读/写来创建互斥锁。

然而,它依赖于提供原子读/写的localStorage。这适用于除Chrome以外的大多数浏览器。

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

3 个答案:

答案 0 :(得分:5)

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

我认为你可能误解了这篇博文,并没有说他的实现在Chrome中不起作用,它不依赖于localStorage提供原子读/写 。他说,普通 localStorage访问权限在Chrome中更具波动性。我假设这与Chrome为每个选项卡使用单独的进程这一事实有关,而大多数其他浏览器倾向于对所有选项卡使用单个进程。他的代码在localStorage之上实现了一个锁定系统,它可以防止被覆盖的东西。

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

答案 1 :(得分:0)

没有。即使浏览器可能在cookie上实现读取和写入锁定,它也不会保护您免受读取和后续写入之间发生的更改。通过查看javascript API for cookies很容易看到,那里没有互斥功能......

答案 2 :(得分:0)

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

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

我尝试了上述问题中提到的Benjamin Dumke-von der Ehe的锁定机制但是得到了不希望的结果。所以我决定推出自己的实验代码:

localStorage lock:

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 回调);

  • lockName - 锁定字符串的全局范围唯一名称 -
  • maxHold - 以毫秒为单位保护脚本的最长时间 - 整数
  • 回调 - 包含受保护脚本的函数

例如:&#34;只在一个标签中播放声音&#34;

//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');                        
    }  
});