Java写入Cookie的GMT时间字符串,JS解析Date返回NaN问题求助
解决Java生成的GMT时间字符串在JS中
Date.parse返回NaN的问题 我来帮你排查这个问题——核心原因是你在Java中使用的date.toGMTString()是已过时的方法,它生成的时间格式属于非标准格式,不同浏览器对Date.parse()解析这种格式的支持不一致,导致你拿到了NaN。下面给你两种解决方案:
方案一:修改Java代码,生成标准ISO 8601格式的时间字符串(推荐)
Java的toGMTString()早就被标记为过时,官方推荐使用符合ISO 8601标准的时间格式,这种格式能被JS的Date对象完美解析。
Java 8+ 版本写法(更简洁)
public static Cookie addOPBrowserStateCookie(HttpServletResponse response) { int expiresSeconds = 120; Instant expiryInstant = Instant.now().plusSeconds(expiresSeconds); // 生成ISO 8601格式的UTC时间字符串,比如 "2023-11-15T12:00:00Z" String expiryTime = DateTimeFormatter.ISO_INSTANT.format(expiryInstant); Cookie cookie = new Cookie(OIDCSessionConstants.OPBS_COOKIE_ID, UUID.randomUUID().toString() + "_" + expiryTime); cookie.setSecure(true); cookie.setPath("/"); response.addCookie(cookie); return cookie; }
兼容Java 7及以下版本写法
public static Cookie addOPBrowserStateCookie(HttpServletResponse response) { int expiresSeconds = 120; Date date = new Date(); date = new Date(date.getTime() + 1000 * expiresSeconds); // 用SimpleDateFormat生成标准ISO 8601格式的UTC时间 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); sdf.setTimeZone(TimeZone.getTimeZone("UTC")); String expiryTime = sdf.format(date); Cookie cookie = new Cookie(OIDCSessionConstants.OPBS_COOKIE_ID, UUID.randomUUID().toString() + "_" + expiryTime); cookie.setSecure(true); cookie.setPath("/"); response.addCookie(cookie); return cookie; }
修改后,你的原有JS代码里Date.parse(c[1])就能正常工作了,不需要改动JS部分。
方案二:如果无法修改Java代码,在JS中手动解析GMT格式字符串
如果你没办法调整Java端的代码,可以写一个自定义解析函数来处理toGMTString()生成的格式(比如Wed, 15 Nov 2023 12:00:00 GMT):
function getOPBrowserState() { var name = "opbs="; var cookie = document.cookie + ";"; var start = cookie.indexOf(name); var opbs = null; if (start != -1) { var end = cookie.indexOf(";", start); opbs = cookie.substring(start + name.length, end); } if (!opbs) return null; console.log(opbs); var c = opbs.split('_'); var result = c[0]; var expiryStr = c[1]; // 自定义GMT字符串解析函数 function parseGMTTime(gmtStr) { const monthMap = { Jan: 0, Feb: 1, Mar: 2, Apr: 3, May: 4, Jun: 5, Jul: 6, Aug: 7, Sep: 8, Oct: 9, Nov: 10, Dec: 11 }; const parts = gmtStr.split(' '); // 提取年、月、日、时、分、秒 const year = parseInt(parts[3], 10); const month = monthMap[parts[2]]; const day = parseInt(parts[1], 10); const [hours, minutes, seconds] = parts[4].split(':').map(Number); // 用UTC时间创建Date对象,避免时区问题 return new Date(Date.UTC(year, month, day, hours, minutes, seconds)); } var expiryDate = parseGMTTime(expiryStr); var now = Date.now(); console.log(expiryDate.getTime().toString()); if (expiryDate.getTime() < now) { return null; } else { return result; } }
这个函数手动拆解GMT字符串的各个部分,然后用Date.UTC()创建标准的Date对象,避免了浏览器对非标准格式解析的兼容性问题。
内容的提问来源于stack exchange,提问作者sathya
相关产品推荐
相关产品推荐

