43

我似乎找不到任何方法来使用JavaFX 中的WebEngine / WebView以编程方式设置 cookie。API 没有提供关于如何获取类似 HttpRequest 的对象以修改标头(这是我在应用程序中用于 XML-RPC 的)或任何类型的 cookie 管理器的任何想法。

这个页面上的问题似乎也没有涉及到这个问题 - 有这个,但它只是在小程序中禁用 cookie 来修复错误,我的应用程序在桌面上。

我想我能做到的唯一方法是请求第一页(这需要一个带有 sessionID 的 cookie 才能正确加载),获取“拒绝访问”样式的消息,在设置 cookie 的页面上下文中执行一些 javascript 和然后令人耳目一新。不过,这种解决方案将是一种糟糕的用户体验。

如何使用 WebEngine 设置 cookie?


更新:从上面链接的问题中获取线索,我尝试挖掘一些使用CookieManager和相关 API 的示例。我发现了这段代码,然后我尝试将其合并到我的应用程序中,但结果很奇怪;

MyCookieStore cookie_store = new MyCookieStore();
CookieManager cookie_manager = new CookieManager(cookie_store, new MyCookiePolicy());
CookieHandler.setDefault(cookie_manager);
WebView wv = new WebView();

现在假设我们这样做:

String url = "http://www.google.com/";
wv.getEngine.go(url);

发出此请求后在 Eclipse 中进行调试显示 cookie 存储映射包含一个 cookie:

{http://www.google.com/=[NID=67=XWOQNK5VeRGEIEovNQhKsQZ5-laDaFXkzHci_uEI_UrFFkq_1d6kC-4Xg7SLSB8ZZVDjTUqJC_ot8vaVfX4ZllJ2SHEYaPnXmbq8NZVotgoQ372eU8NCIa_7X7uGl8GS, PREF=ID=6505d5000db18c8c:FF=0:TM=1358526181:LM=1358526181:S=Nzb5yzBzXiKPLk48]}

太棒了

WebEngine 只是使用底层注册的 cookie 引擎!但是等等,真的吗?让我们尝试在发出请求之前添加一个 cookie...

cookie_store.add(new URL(url).toURI(), new HttpCookie("testCookieKey", "testCookieValue"));

然后我在Wireshark中查看请求...

GET / HTTP/1.1
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/535.14 (KHTML, like Gecko) JavaFX/2.2 Safari/535.14
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Cache-Control: no-cache
Pragma: no-cache
Host: www.google.com
Connection: keep-alive

我没有饼干 :(

我究竟做错了什么?

4

2 回答 2

48

在 Oracle 的 Vasiliy Baranov 的帮助下,我设法解决了这个问题。瓦西里给我写信:

java.net.CookieHandler.getDefault()尝试在第一次实例化 WebView 之后和调用之前 将 cookie 放入WebEngine.load,例如如下:

WebView webView = new WebView();
URI uri = URI.create("http://mysite.com");
Map<String, List<String>> headers = new LinkedHashMap<String, List<String>>();
headers.put("Set-Cookie", Arrays.asList("name=value"));
java.net.CookieHandler.getDefault().put(uri, headers);
webView.getEngine().load("http://mysite.com");

这会将 cookie 永久放入存储中,它应该在每个后续请求中发送出去(假设服务器没有取消设置它)。

Vasiliy 还解释说,WebView将安装它自己的实现CookieHandler,同时保留放入默认的 cookie。

最后,他提到了一件非常有趣的事情:

不要浪费时间尝试使用java.net.CookieManager, 和 java.net.CookieStore. 它们很可能会导致许多站点出现问题,因为它们实施了错误的标准。

在此之后我尝试使用谷歌搜索,但这似乎不是常识。如果有人能够提供更多详细信息,我将不胜感激。这似乎很奇怪,因为它似乎CookieStore并被CookieManager许多软件使用。

于 2013-01-25T10:25:37.657 回答
2

java.net.CookieManager 的解决方案

Cookie 序列化:

        List<HttpCookie> httpCookies = cookieManager.getCookieStore().getCookies();
        Gson gson = new GsonBuilder().create();
        String jsonCookie = gson.toJson(httpCookies);

Cookie 反序列化:

Gson gson = new GsonBuilder().create();
List<HttpCookie> httpCookies = new ArrayList<>();
Type type = new TypeToken<List<HttpCookie>>() {}.getType();
httpCookies = gson.fromJson(json, type);   // convert json string to list
for (HttpCookie cookie : httpCookies) {
    cookieManager.getCookieStore().add(URI.create(cookie.getDomain()), cookie);
}
于 2018-06-06T10:51:32.367 回答