Cookie值显示为Undefined或NaN的技术问题求助
问题描述
我正在开发一款卡牌游戏计分应用,计划添加Cookie作为数据持久化功能。编写代码后发现,修改Cookie中存储的两个变量值、保存并重新加载页面时,一个变量读取正常,另一个却显示为NaN。通过Firefox调试器确认,页面加载时的Cookie读取函数中,第一个值正常,第二个值为undefined,求解决办法。
相关代码
HTML
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Canasta Scoring</title> <link rel="stylesheet" href="style.css"> <script src="script.js"></script> <script src="https://kit.fontawesome.com/3c78002abf.js" crossorigin="anonymous"></script> </head> <body onload="start()" id="content"> <p class="title">Canasta Scoring</p> <div class="table"> <hr class="blank"> <div class="p1"> <input type="text" value="Player One" class="playertitle"> <hr> <div class="bonus1"> <hr class="blank"> <p class="cat">Bonus</p> <hr class="blank"> <input type="number" name="bonusone" id="bonusnumone" class="num" placeholder="10000"> <hr class="blank"> </div> <div class="count1"> <hr class="blank"> <p class="cat">Card Count</p> <hr class="blank"> <input type="number" name="countone" id="countnumone" class="num" placeholder="345"> <hr class="blank"> </div> <button class="submit" id="subone" onclick="addone()">Submit to Total!</button> <p class="total" id="totalone">####</p> </div> <hr> <div class="p2"> <input type="text" value="Player Two" class="playertitle"> <div class="bonus2"> <hr class="blank"> <p class="cat">Bonus</p> <hr class="blank"> <input type="number" name="bonustwo" id="bonusnumtwo" class="num" placeholder="10000"> <hr class="blank"> </div> <div class="count2"> <hr class="blank"> <p class="cat">Card Count</p> <hr class="blank"> <input type="number" name="counttwo" id="countnumtwo" class="num" placeholder="345"> <hr class="blank"> </div> <button class="submit" id="subtwo" onclick="addtwo()">Submit to Total!</button> <p class="total" id="totaltwo">####</p> </div> <hr class="blank"> </div> <hr class="blank"> <div class="resetbefore" id="resetbefore"> <button class="reset" onclick="ask()">Reset</button> </div> <div class="resetduring" id="resetduring"> <p class="total">Are You Sure?</p> <button class="reset" onclick="reset()">Yes</button> <button class="reset" onclick="cancel()">No</button> </div> <hr class="blank"> <hr class="blank"> <div class="modes"> <button class="color" onclick="dark()"><i class="fa-solid fa-moon fa-6x"></i></button> <button class="color" onclick="light()"><i class="fa-solid fa-sun fa-6x"></i></button> <button class="color" onclick="normal()"><i class="fa-solid fa-palette fa-6x"></i></button> <button class="color" onclick="photo()"><i class="fa-solid fa-diamond fa-6x"></i></button> </div> <hr class="blank"> <hr class="blank"> <p>©2023 David Kolenda</p> <p>All Rights Reserved to Copyright Holders</p> </body> </html>
JavaScript
let onebonus = 0; let twobonus = 0; let onecount = 0; let twocount = 0; let onetotal = 0; let twototal = 0; let oneall = 0; let twoall = 0; function start() { const cookieValue = document.cookie .split("; ") .find((row) => row.startsWith("int1=")); if (cookieValue) { const [, value1, value2] = cookieValue.split(/[=;]/); onetotal = parseInt(value1); twototal = parseInt(value2); } display() } function display() { document.getElementById('totalone').innerHTML = onetotal; document.getElementById('totaltwo').innerHTML = twototal; check() } function check() { if (onetotal > 5000 && twototal > 5000) { if (onetotal > twototal) { document.getElementById('totalone').style.color = 'rgb(255,0,0)'; document.getElementById('totaltwo').style.color = 'rgb(0,0,0)'; } else { document.getElementById('totaltwo').style.color = 'rgb(255,0,0)'; document.getElementById('totalone').style.color = 'rgb(0,0,0)'; } } else { if (onetotal > 5000) { document.getElementById('totalone').style.color = 'rgb(255,0,0)'; } if (twototal > 5000) { document.getElementById('totaltwo').style.color = 'rgb(255,0,0)'; } else { console.log('Neither Player Has Won Yet!') } } saveCookie() } function addone() { onebonus = document.getElementById('bonusnumone').value; onecount = document.getElementById('countnumone').value; oneall = parseInt(onebonus) + parseInt(onecount); onetotal = parseInt(onetotal) + parseInt(oneall); oneall = 0; onebonus = 0; document.getElementById('countnumone').value = 0; document.getElementById('bonusnumone').value = 0; display() } function addtwo() { twobonus = document.getElementById('bonusnumtwo').value; twocount = document.getElementById('countnumtwo').value; twoall = parseInt(twobonus) + parseInt(twocount); twototal = parseInt(twototal) + parseInt(twoall); twoall = 0; twobonus = 0; document.getElementById('countnumtwo').value = 0; document.getElementById('bonusnumtwo').value = 0; display() } function dark() { document.getElementById('content').style.backgroundImage = 'linear-gradient(180deg, rgb(0, 0, 0), rgb(0, 0, 0))'; document.getElementById('content').style.color = 'white'; display() } function light() { document.getElementById('content').style.backgroundImage = 'linear-gradient(180deg, rgb(255, 255, 255), rgb(255, 255, 255))'; document.getElementById('content').style.color = 'black'; display() } function normal() { document.getElementById('content').style.backgroundImage = 'linear-gradient(180deg, rgb(112, 222, 21), rgb(77, 201, 15))'; document.getElementById('content').style.color = 'black'; display() } function photo() { document.getElementById('content').style.backgroundImage = 'url(background.png)'; document.getElementById('content').style.color = 'black'; display() } function ask() { document.getElementById('resetbefore').style.display = 'none'; document.getElementById('resetduring').style.display = 'inline'; } function cancel() { document.getElementById('resetbefore').style.display = 'inline'; document.getElementById('resetduring').style.display = 'none'; } function reset() { document.getElementById('resetbefore').style.display = 'inline'; document.getElementById('resetduring').style.display = 'none'; onebonus = 0; twobonus = 0; onecount = 0; twocount = 0; onetotal = 0; twototal = 0; oneall = 0; twoall = 0; display() } function saveCookie() { document.cookie = `int1=${onetotal};int2=${twototal}`; }
CSS
body { display: flex; flex-direction: column; justify-content: center; text-align: center; font-family: Arial, Helvetica, sans-serif; background-image: url('background.png'); color: black; } .title { font-size: 60px; font-weight: 999; } .table { display: flex; flex-direction: row; justify-content: center; } .blank { visibility: hidden; } .p1 { border: 1px #313131 solid; display: grid; border-radius: 15px; padding: 10px; } .p2 { border: 1px #313131 solid; display: grid; border-radius: 15px; padding: 10px; } .bonus1 { display: flex; flex-direction: row; padding: 10px; justify-content: center; } .count1 { display: flex; flex-direction: row; padding: 10px; justify-content: center; } .bonus2 { display: flex; flex-direction: row; padding: 10px; justify-content: center; } .count2 { display: flex; flex-direction: row; padding: 10px; justify-content: center; } .playertitle { font-size: 30px; font-weight: 500; text-align: center; background: none; border: none; border-radius: 15px; transition: 0.2s ease-out; } .playertitle:hover { background-color: rgba(255,255,255,0.455); border: 1px solid black; } .submit { background-color: rgba(19, 225, 132, 0.625); font-size: x-large; border-radius: 15px; transition: 0.2s ease-out; border: none; } .submit:hover { background-color: rgba(19, 225, 132, 1); font-size: xx-large; } .cat { font-size: large; font-weight: bold; } .total { font-size: xx-large; font-weight: 1000; } .count2 { display: flex; flex-direction: row; padding: 10px; } .num { text-align: center; background-color: rgb(25, 101, 233); color: white; border-radius: 15px; border: none; transition: 0.2s; } .num:focus { font-size: large; } .color { width: min-content; background-color: rgba(255,255,255,0.5); border: none; border-radius: 15px; transition: 0.2s ease-out; } .color:hover { background-color: rgba(255,255,255,0.75); } .reset { background-color: rgb(240, 12, 12); color: white; font-size: 25pt; border: none; border-radius: 15px; transition: 0.2s; } .reset:hover { background-color: white; color: black; font-size: 45pt; } .resetduring { display: none; }
问题根源与修复方案
问题核心
- Cookie存储格式错误:
saveCookie函数中,两个Cookie键值对之间缺少空格,正确的分隔符应为;(分号+空格),当前写法int1=${onetotal};int2=${twototal}会让浏览器把int2=xxx识别为int1Cookie的附加属性,而非独立Cookie。 - 读取逻辑错误:
start函数仅尝试读取以int1=开头的Cookie行,且拆分逻辑错误,无法正确提取第二个值。
修复方案(推荐拆分独立Cookie,更规范)
1. 修改Cookie存储函数
function saveCookie() { // 给Cookie添加path=/,确保全站可访问 document.cookie = `int1=${onetotal}; path=/`; document.cookie = `int2=${twototal}; path=/`; }
2. 修改Cookie读取函数
function start() { // 读取玩家1的总分 const int1Cookie = document.cookie.split("; ").find(row => row.startsWith("int1=")); if (int1Cookie) { onetotal = parseInt(int1Cookie.split("=")[1], 10); } // 读取玩家2的总分 const int2Cookie = document.cookie.split("; ").find(row => row.startsWith("int2=")); if (int2Cookie) { twototal = parseInt(int2Cookie.split("=")[1], 10); } display(); }
额外优化建议
- 使用
parseInt时添加第二个参数10,明确按十进制解析,避免非预期的八进制解析问题。 - 可以给Cookie添加过期时间(如
expires=xxx),避免会话结束后Cookie丢失。
内容的提问来源于stack exchange,提问作者David Kolenda
相关产品推荐
相关产品推荐

