2012-12-13 19 views
6

Tôi đang làm việc theo số deck building application cho trò chơi bài tôi chơi. Tôi đang sử dụng localStorage để lưu và truy xuất các bộ bài. Dường như nó hoạt động hoàn hảo trong Chrome, nhưng trong Firefox nó hoạt động không ổn định.localStorage không đáng tin cậy trong Firefox

Trong FF, mọi thứ dường như hoạt động tốt lúc đầu, boong tàu thậm chí còn lưu thông qua tải lại. Tuy nhiên, nếu tôi thêm một boong thứ hai và tải lại, nó chỉ tìm thấy boong đầu tiên. Nếu tôi xóa boong đầu tiên, nó sẽ không còn tìm thấy gì nữa.

Tất cả tương tác lưu trữ cục bộ nằm trong tập lệnh/vault.js, mà tôi sẽ tạo lại bên dưới. Tôi có làm điều gì sai?

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

Về cơ bản, có vẻ như tại một số điểm, các khóa trong localStorage bị 'cố định' vì thiếu cụm từ tốt hơn; localStorage sẽ hoạt động chính xác trong khi tôi thao tác nó, nhưng ngay sau khi tôi làm mới trang, nó dường như hoàn nguyên về trạng thái nào nó đã bị đóng băng.

+0

Bạn có thể tạo bản trình diễn http://jsfiddle.net không? –

+1

Tôi đã đăng liên kết tới ứng dụng trong bài đăng đầu tiên của mình. Đây là một lần nữa: http://asmor.com/anr/ – Asmor

+0

Vâng, nếu nó trong một fiddle, tôi có thể làm việc với mã và kiểm tra những thứ khác nhau. Nó không cần thiết, nhưng nó sẽ làm cho nó nhiều khả năng bản thân mình và một số người khác sẽ tinker với nó để xem nếu chúng ta có thể tìm ra nó. –

Trả lời

3

Tôi đã gặp phải vấn đề này một vài lần và lúc đầu tôi không lưu ý lý do tại sao nó không thể đọc localStorage, nhưng tôi nghĩ rằng tôi đã tìm thấy một giải pháp cho điều đó.

Các hoạt động cục bộ lưu trữ là tất cả các trình duyệt đồng bộ và khác nhau có một số gợi ý nhất định về cách chúng xử lý chúng.

Trong trường hợp của bạn, vấn đề có vẻ là bạn đang cố gắng đọc localStorage trước khi DOM sẵn sàng. Tôi đã thử nó với Firebug và tôi đã thêm một điểm ngắt vào đầu tệp vault.js và tải lại trang và khi mã bị ngắt, tôi kiểm tra tab dom và tìm thuộc tính localStorage, và ở đó - danh sách đầy đủ được lưu trữ giá trị. Khi tôi xóa điểm ngắt và tải lại trang, tất cả đều đã biến mất sau khi trang được tải.

Điều này có thể là một lỗi trong Firefox hoặc các trình duyệt khác chỉ cần khởi chạy localStorage nhanh hơn.

Vì vậy, như một giải pháp cho vấn đề của bạn: hãy thử tìm nạp khóa từ localStorage SAU DOM đã sẵn sàng.

+0

Cảm ơn. Trong khi đề xuất của bạn dường như không phải là nguyên nhân của nó, nó đã làm cho tôi đi trên một ca khúc để tìm một giải pháp hacky dưới đây. Tôi vẫn muốn tìm lý do thực tế này không hoạt động và làm cho nó hoạt động chính xác. – Asmor

+0

Nó thực sự là một lỗi rất lạ. Dường như nếu bạn tạm dừng tải trang trước khi nó được tải, và sau đó tiếp tục, các giá trị ở đó, nhưng nếu bạn để trang tải đầu tiên, chúng sẽ biến mất. Nó giống như một cái gì đó cố gắng truy cập nó trước khi nó sẵn sàng và trình duyệt không thể khởi tạo localStorage. Có thể đáng để nộp một lỗi cho Mozilla, nhưng thật khó để tái sản xuất. – jylauril

+0

Đã một vài ngày và tôi không thấy bất kỳ hoạt động nào về vấn đề này, vì vậy tôi sẽ tiếp tục và đánh dấu bạn là câu trả lời được chấp nhận. Cảm ơn vì đã giúp tôi đi đúng hướng! – Asmor

0

jylauril đang đi đúng hướng, tôi nghĩ vậy.

Tôi đã chơi với sự chậm trễ và nhận thấy một số hành vi kỳ lạ. Theo như tôi có thể nói, có vẻ như nếu bạn chạm vào localStorage trước khi TẤT CẢ JavaScript đã hoàn thành việc thực thi, bao gồm JS làm setTimeout, localStorage sẽ xuất hiện trống cho lần truy cập trang đó. Ví dụ:

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

Firebug của giao diện điều khiển:

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 

tôi nghĩ rằng tôi có thể là trên một cái gì đó, nhưng lý thuyết của tôi cho đến nay đã chứng minh là sai. Một điều kỳ lạ tôi đã nhận thấy, mặc dù. Bất kể bao lâu tôi chờ đợi, nếu tôi cố gắng nhìn lên sàn đầu tiên, nó sẽ thất bại và lưu trữ địa phương sẽ trống:

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

Nhưng nếu tôi làm những theo thứ tự ngược lại ...

>>> 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"}] 

Nếu tôi đăng nhập localStorage trong hàm, nó hoạt động cũng như:

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; 
}; 

nó hoạt động.Nếu tôi hủy bỏ nó, mặc dù ...

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; 
}; 

Nó không hoạt động. Nó cũng không hoạt động nếu tôi loại bỏ từ khóa void và chỉ có localStorage như một câu lệnh.

Tôi không biết tại sao, nhưng console.log (localstorage) dường như sửa lỗi này và tôi có thể gọi localStorage bất cứ khi nào tôi muốn.

Thật kỳ lạ.

EDIT: Tôi tìm thấy giải pháp tốt hơn một chút. Việc gọi thuộc tính 'length' của localStorage cũng hoạt động.

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; 
}; 

Đây là một chút tốt hơn ở chỗ nó không đăng bất cứ điều gì ...

+0

Trong khi điều này dường như không hoạt động, tôi để lại câu hỏi này mở với hy vọng ai đó có thể giải thích vấn đề và/hoặc cung cấp một giải pháp không phải là một hack xấu xí. – Asmor

-2

• Để đảm bảo rằng dữ liệu localStorage được làm sẵn có một cách nhất quán trong tất cả các trang html: o miền (bối cảnh địa phương) phải giống nhau. o Đảm bảo giữ các thẻ < < script >> giống hệt nhau trong tất cả các tệp Html, o (chỉ Firefox) đảm bảo onPageLoad được giữ nguyên trong tất cả các tệp JavaScript (được thêm vào tệp html), tức là đảm bảo thêm cùng một hàm tới PageLoadEvent.

1

Mặc dù đây là một bài đăng cũ nhưng nghĩ rằng phát hiện của tôi có thể hữu ích. Tôi cũng phải đối mặt với cùng một vấn đề vì vậy tôi đã đi qua bài đăng này, thử điều này và đây là những gì tôi đã nhận thấy, trong firefox nếu bạn cố gắng làm bất cứ điều gì (ngay cả một localStorage.getItem) với localstorage trước window.load nó sẽ xóa mọi thứ khỏi nó và bạn sẽ không có gì cả. Vì vậy, bất cứ điều gì bạn muốn làm thiết lập hoặc nhận được, làm điều đó sau khi window.load.

Something như thế này

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

BTW Tôi đã cố gắng để làm một số thao tác với localStorage tại document.ready trước khi điều này được không.

Các vấn đề liên quan