
HtmlUnit 3.4.0+ 提供了原生支持 LocalStorage 的 API,可通过 WebClient.getStorageHolder().getLocalStorage(url) 获取指定域名的存储实例,直接操作 Map 即可预置数据,无需依赖 JavaScript 执行,更可靠、更符合浏览器行为。
htmlunit 3.4.0+ 提供了原生支持 localstorage 的 api,可通过 `webclient.getstorageholder().getlocalstorage(url)` 获取指定域名的存储实例,直接操作 map 即可预置数据,无需依赖 javascript 执行,更可靠、更符合浏览器行为。
在早期版本中,开发者常通过 executeJavaScript("localStorage.setItem(...)") 方式注入 LocalStorage 数据,但这种方式存在明显缺陷:
- 执行时机不可控(如在页面未初始化 storage 时调用会静默失败);
- 无法跨页面共享(尤其在重定向或新页面加载后丢失);
- 难以验证是否真正写入(
executeJavaScript不抛异常,也不返回结果)。
✅ 正确做法(HtmlUnit ≥ 3.4.0):使用 StorageHolder 统一管理
HtmlUnit 3.4.0 引入了标准化的 StorageHolder 机制,将 LocalStorage 和 SessionStorage 抽象为与 URL 绑定的线程安全 Map。其核心逻辑是:LocalStorage 按源(origin)隔离,因此必须传入与目标页面完全匹配的 base URL(协议 + 域名 + 端口)。
try (WebClient webClient = new WebClient()) {
// Step 1: 获取目标 URL 对应的 LocalStorage 映射(自动创建)
String targetUrl = "https://example.com/app";
Map<String, String> localStorage = webClient.getStorageHolder()
.getLocalStorage(targetUrl); // 注意:必须与 getPage() 的 URL 同源
// Step 2: 预置键值对(支持中文、JSON 字符串等,自动编码)
localStorage.put("user_token", "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...");
localStorage.put("theme", "dark");
localStorage.put("preferences", "{\"language\":\"zh-CN\",\"notifications\":true}");
// Step 3: 加载页面(此时页面 JS 可立即读取 localStorage)
HtmlPage page = webClient.getPage(targetUrl);
webClient.waitForBackgroundJavaScript(3000);
// Step 4: 验证写入是否生效(直接读 Map,无需 JS 调用)
System.out.println("Stored token: " + localStorage.get("user_token")); // ✅ 输出预期值
}⚠️ 关键注意事项:
立即学习“前端免费学习笔记(深入)”;
-
URL 必须精确匹配:
getLocalStorage("https://example.com")与getLocalStorage("https://example.com/")视为不同 origin;建议统一使用webClient.getCurrentWindow().getEnclosedPage().getFullyQualifiedUrl()获取规范 URL。 -
不支持通配符或子路径继承:
https://example.com/a和https://example.com/b的 LocalStorage 是隔离的,需分别设置。 -
线程安全:
StorageHolder内部使用ConcurrentHashMap,多线程环境下可安全读写。 -
清除方式:调用
localStorage.clear()或webClient.getStorageHolder().clearAllStorages()。
? 如何调试与验证?
除直接读取 Map 外,也可通过 JavaScript 辅助确认:
String actualValue = (String) page.executeJavaScript(
"localStorage.getItem('user_token')"
).getJavaScriptResult();
assertNotNull(actualValue);综上,摒弃 executeJavaScript 注入方式,改用 StorageHolder 是 HtmlUnit 中操作 LocalStorage 的唯一推荐方案——它语义清晰、行为可预测、调试友好,且完全对齐 Web 标准规范。


















