2012-12-13 4 views
6

나는 내가 플레이하는 카드 게임에 대해 deck building application에서 일하고 있습니다. 저는 localStorage를 사용하여 데크를 저장하고 검색합니다. Chrome에서 완벽하게 작동하는 것으로 보이지만 Firefox에서는 신뢰성이 떨어집니다.Firefox에서 신뢰할 수없는 localStorage

FF에서는 처음에는 모든 것이 정상적으로 작동하는 것으로 보입니다. 갑판은 재 장전까지 지속됩니다. 그러나 두 번째 데크를 추가하고 다시로드하면 첫 번째 데크 만 찾습니다. 첫 번째 덱을 삭제하면 더 이상 아무것도 찾을 수 없습니다.

모든 로컬 저장소 상호 작용은 scripts/vault.js에 있으며, 아래에서 재현합니다. 내가 뭔가 잘못하고 있는거야?

vault = {}; 
vault.makeKey = function (s) { 
    return "deck:" + s; 
}; 
vault.friendlyName = function(s) { 
    if (s.indexOf("deck:") === 0) { 
     return s.substring(5); 
    } else { 
     return s; 
    } 
}; 
vault.store = function (deck, name) { 
    if (!window.localStorage) { 
     alert("This browser doesn't support local storage. You will be unable to save decks."); 
     return; 
    } 
    var key = vault.makeKey(name); 
    localStorage.setItem(key, deck.export()); 
}; 
vault.retrieve = function (key) { 
    deck.import(localStorage[key]); 
}; 
vault.getDecks = function() { 
    var keys = Object.keys(localStorage), 
     out = [], 
     i, 
     k, 
     name = ""; 
    for (i = 0; i < keys.length; i++) { 
     k = keys[i]; 
     name = vault.friendlyName(k); 
     if (name !== k && localStorage[k]) { 
      out.push({name: name, key: k}); 
     } 
    } 
    out.sort(function (a, b) { 
     return a.name > b.name ? 1 : -1; 
    }); 
    return out; 
}; 
vault.deleteDeck = function (key) { 
    localStorage.removeItem(key); 
}; 

기본적으로 localStorage의 키가 더 나은 용어가 부족하여 '고정'되는 것처럼 보입니다. localStorage는 조작하는 동안 올바르게 동작하지만 페이지가 새로 고쳐지면 고정 된 상태로 되돌아가는 것처럼 보입니다.

+0

http://jsfiddle.net 데모를 만들 수 있습니까? –

+1

첫 번째 게시물에 응용 프로그램 자체에 대한 링크를 게시했습니다. 여기 다시 있습니다 : http://asmor.com/anr/ – Asmor

+0

글쎄, 그것이 피들에 있다면, 나는 코드로 작업하고 다른 것들을 점검 할 수 있습니다. 필요하지는 않지만 자신을 만들 가능성이 높아지고 다른 사람들도 우리가 알아낼 수 있는지 알아보기 위해 그 도구를 고칠 것입니다. –

답변

3

나는이 문제를 몇 번이나 실행했지만 처음에는 그렇지 않았습니다. localStorage를 읽을 수없는 이유를 확인하십시오.하지만 그 해결책을 찾은 것 같습니다.

로컬 스토리지 작업은 모든 동기와 다른 브라우저들이이를 처리하는 방법에 대한 특정 단점을 가지고 있습니다. 귀하의 경우에는

는, 문제는 당신이 DOM이 준비되기 전에 로컬 스토리지를 읽을하려는 것 같다. Firebug로 시도해 보았고 vault.js 파일의 시작 부분에 중단 점을 추가하고 페이지를 다시로드하고 코드가 깨지면 dom-tab을 확인하고 localStorage 속성을 찾았습니다. 거기에는 저장된 전체 목록 값. 중단 점을 제거하고 페이지를 다시로드하면 페이지가로드되고 나면 모두 사라졌습니다.

Firefox 또는 다른 브라우저의 버그 일 수 있습니다. localStorage를 더 빨리 초기화하십시오.

그래서, 문제에 대한 해결책으로 다음 DOM이 준비되면 로컬 스토리지에서 키를 가져 오는 시도합니다.

+0

감사합니다. 귀하의 제안이 그 원인이 아닌 것처럼 보이지만, 아래에 해킹 된 해결책을 찾기 위해 트랙에 올라 가게했습니다. 나는 여전히 작동하지 않는 실제 이유를 찾고 올바르게 작동하게하고 싶습니다. – Asmor

+0

정말 이상한 버그입니다. 로드되기 전에 페이지 로딩을 일시 중지했다가 다시 시작하면 값이 표시되지만 페이지를 먼저로드하게하면 페이지가 사라지는 것으로 보입니다. 그것은 준비가되기 전에 무언가가 브라우저에 액세스하려고 시도하고 브라우저가 localStorage를 초기화하지 못하는 것입니다. Mozilla에 버그를 제출할 가치가 있지만 재현하기가 어렵습니다. – jylauril

+0

며칠이 지났으나 이것에 관해 어떤 활동도 보지 않고 있습니다. 그래서 나는 당신을 받아 들여진 대답으로 표시 할 것입니다. 올바른 길을 찾아 주셔서 감사합니다! – Asmor

0

jylauril이 올바른 길이라고 생각합니다.

나는 지연으로 놀았고, 이상한 행동을 감지했다.

는 지금까지 내가 말할 수있는, 당신이 JS이의 setTimeout 일을 포함하여, 모든 전에 모든 자바 스크립트가 완료 실행 로컬 스토리지를 만지면 것 같아, 로컬 스토리지는 페이지 뷰 빈 나타납니다. 예를 들면 :

$(window).load(function() { 
    console.log("Waiting 10000ms", new Date()); 
    setTimeout(setDeckSelect, 10000); 
}); 

방화범의 콘솔 : 나는 뭔가에있을 수 있습니다 생각하지만 내 이론은 지금까지 잘못 입증

Waiting 10000ms Date {Thu Dec 13 2012 10:35:48 GMT-0500 (Eastern Standard Time)} 
exec.js (line 191) 
getDecks Date {Thu Dec 13 2012 10:35:58 GMT-0500 (Eastern Standard Time)} 
vault.js (line 23) 
>>> localStorage 
0 items in Storage 

. 내가 알아 차 렸던 이상한 일. 에 관계없이 내가 먼저 데크를 검색하려고하면 나는, 대기 시간, 그것은 실패하고 로컬 저장소가 비어있을 것입니다 :

>>> vault.getDecks() 
[] 
>>> localStorage 
0 items in Storage 

을하지만 반대 순서로 사람들을한다면 ...

>>> localStorage 
8 items in Storage deck:dfs= 
"{"identity":"MakingNews","cards":{}}", deck:ngrngfrn= "{"identity":"BuildingaBetterWorld","cards":{}}", deck:sdfgshsh= "{"identity":"MakingNews","cards":{}}", deck:sdfgdgdfg= "{"identity":"MakingNews","cards":{}}", deck:dfgdfgas= "{"identity":"EngineeringtheFuture","cards":{}}", deck:sdfsga= "{"identity":"MakingNews","cards":{}}", deck:gdgd= "{"identity":"MakingNews","cards":{}}", deck:gfsdfgsdfg= "{"identity":"BuildingaBetterWorld","cards":{}}" 
>>> vault.getDecks() 
[Object { name= "dfgdfgas", key= "deck:dfgdfgas"}, Object { name= "dfs", key= "deck:dfs"}, Object { name= "gdgd", key= "deck:gdgd"}, Object { name= "gfsdfgsdfg", key= "deck:gfsdfgsdfg"}, Object { name= "ngrngfrn", key= "deck:ngrngfrn"}, Object { name= "sdfgdgdfg", key= "deck:sdfgdgdfg"}, Object { name= "sdfgshsh", key= "deck:sdfgshsh"}, Object { name= "sdfsga", key= "deck:sdfsga"}] 
나는 함수에 로컬 스토리지를 로그인하는 경우

, 그것은뿐만 아니라 작동합니다

vault.getDecks = function() { 
    console.log(localStorage); 
    var keys = Object.keys(localStorage), 
     out = [], 
     i, 
     k, 
     name = ""; 
    for (i = 0; i < keys.length; i++) { 
     k = keys[i]; 
     name = vault.friendlyName(k); 
     if (name !== k && localStorage[k]) { 
      out.push({name: name, key: k}); 
     } 
    } 
    out.sort(function (a, b) { 
     return a.name > b.name ? 1 : -1; 
    }); 
    return out; 
}; 

가 작동합니다.비록 내가 그것을 무효로한다면 ...

vault.getDecks = function() { 
    // console.log(localStorage); 
    void localStorage; 
    var keys = Object.keys(localStorage), 
     out = [], 
     i, 
     k, 
     name = ""; 
    for (i = 0; i < keys.length; i++) { 
     k = keys[i]; 
     name = vault.friendlyName(k); 
     if (name !== k && localStorage[k]) { 
      out.push({name: name, key: k}); 
     } 
    } 
    out.sort(function (a, b) { 
     return a.name > b.name ? 1 : -1; 
    }); 
    return out; 
}; 

그것은 작동하지 않습니다. 또한 void 키워드를 제거하고 statement로만 localStorage를 사용하면 작동하지 않습니다.

이유는 모르겠지만 console.log (localstorage)가이 문제를 해결하는 것으로 보입니다. 필요할 때마다 localStorage를 호출 할 수 있습니다.

이상한 괴물.

편집 : 약간 더 나은 해결책을 찾았습니다. localStorage의 '길이'속성을 호출하는 것도 효과가 있습니다. 이는 아무것도 기록하지 않는다는 점에서 좀 더

vault.getDecks = function() { 
    //Weird hack to make FF load localStorage correctly... 
    localStorage.length; 
    var keys = Object.keys(localStorage), 
     out = [], 
     i, 
     k, 
     name = ""; 
    for (i = 0; i < keys.length; i++) { 
     k = keys[i]; 
     name = vault.friendlyName(k); 
     if (name !== k && localStorage[k]) { 
      out.push({name: name, key: k}); 
     } 
    } 
    out.sort(function (a, b) { 
     return a.name > b.name ? 1 : -1; 
    }); 
    return out; 
}; 

...

+0

이것이 효과가있는 것처럼 보이지만 누군가가 문제를 설명하거나 못생긴 해킹이 아닌 해결책을 제공 할 수 있기를 희망하여이 질문을 공개합니다. – Asmor

-2

• 그 로컬 스토리지의 데이터를 보장하기 위해 지속적으로 모든 HTML 페이지에서 사용할 수 있습니다 : 도메인 (로컬 컨텍스트) 오 해야 동일 하십시요. o 모든 HTML 파일에서 < < 스크립트 >> 태그를 동일하게 유지하십시오 (Firefox 만 해당). onPageLoad가 모든 JavaScript 파일 (HTML 파일에 추가됨)에서 동일하게 유지되는지 확인하십시오. 즉, 동일한 기능을 추가해야합니다. PageLoadEvent에 전달합니다.

1

비록 이것이 오래된 게시물이지만 내 발견이 도움이 될 수 있다고 생각합니다. 나는 또한이 문제를 직면했다 그래서이 게시물을 통해 시도하고이 파이어 폭스, window.load 전에 모든 것을 제거합니다 localstorage 함께 (심지어 localStorage.getItem)하려고하면 내가 알아 챘을 것입니다 그것과 당신은 아무것도 가질 수 없습니다. 따라서 설정하거나 가져 오려는 것이 무엇이든 window.load 후에 수행하십시오. 이

$(window).load(function() { 
    //do whatever you want to do with localstorage 
}); 

같은

뭔가 BTW 나는 실패 된이 전에 document.ready에서 로컬 스토리지와 일부 작업을하려고했다.

관련 문제