【问题标题】:Selenium cookie with another domainSelenium cookie 与另一个域
【发布时间】:2014-04-25 18:39:08
【问题描述】:

我有一个关于 selenium 的代码来测试表单。但首先我转到另一个页面,然后重定向到我的页面。当我将 cookie 设置为新域时,出现错误:

Exception in thread "main" org.openqa.selenium.InvalidCookieDomainException: You may only set cookies for the current domain

我的代码:

//it is going to example.com and example redirect me to the "example.com" all cookie domains is "example.com"
driver.get("http://www.example.com?id=1");

 Set<Cookie> cookies = driver.manage().getCookies();
 Iterator<Cookie> itr = cookies.iterator();

    while (itr.hasNext()){
    Cookie c = itr.next();
    System.out.println("Cookie Name: " + c.getName() + " --- " + "Cookie Domain: " + c.getDomain() + " --- " + "Cookie Value: " + c.getValue());

    driver.manage().addCookie(c);
    }

我该如何管理?我必须为 example.com 获取/设置 cookie

【问题讨论】:

  • 根据报错:You may only set cookies for the current domain你不能那样做。

标签: java cookies selenium


【解决方案1】:

就像前面的回答中提到的,这是预期的行为。

迄今为止唯一的解决方法是driver.get("domain.com/404") 页面。但这并不总是有效,因为 SSO 经常保护 domain.com/*

我对规范提出了新功能请求:https://github.com/w3c/webdriver/issues/1238

使 404 解决方法始终有效。

网络驱动程序规范 https://w3c.github.io/webdriver/webdriver-spec.html#add-cookie部队 当前浏览器会话位于您要添加的域上 cookie 到。

这很有意义,我同意。

不幸的是,这阻止了 2 个关键用例:

您想在新的网络驱动程序会话中重用 cookie 会话以避免重复获取 cookie 所需的工作。这样的 因为必须重复登录。允许共享 webdriver 池 在不相关的线程中,每个线程可能有自己的 饼干。当前唯一的解决方法是尝试强制 webdriver 转到 404 错误页面,如下所示: webdriver.get("http://the-cookie-domain.com/404adsfasdf")。这个会 导致页面转到域,并允许您添加 cookie 添加Cookie。但这几乎没有用。因为页面经常 受 SSO 保护,任何访问 http://the-cookie-domain.com/* 的尝试 将您发送到 SSO 登录页面,例如http://login.ssodomain.com 现在 你有同样的问题。

我们应该在规范 webdriver.goTo404Page(domain) 中添加一个新方法 允许这个用例。此方法应模拟 404 HTTP 状态 来自浏览器中域的代码响应。

或者可能是 addCookie 的新重载可以允许这样做, 例如: void addCookie(Cookie var1, String goTo404PageOfDomain);

通过允许用户访问任何给定域的虚假 404 页面,这 保证 404 页的解决方法适用于任何页面,并且这两个使用 案例现在是可能的。

对于 Firefox,您可以稍微修改 Marionette 以删除此检查。

diff --git a/testing/marionette/cookie.js b/testing/marionette/cookie.js
--- a/testing/marionette/cookie.js
+++ b/testing/marionette/cookie.js
@@ -144,14 +144,14 @@ cookie.add = function(newCookie, {restri
     newCookie.domain = "." + newCookie.domain;
   }

-  if (restrictToHost) {
-    if (!restrictToHost.endsWith(newCookie.domain) &&
-        ("." + restrictToHost) !== newCookie.domain &&
-        restrictToHost !== newCookie.domain) {
-      throw new InvalidCookieDomainError(`Cookies may only be set ` +
-          `for the current domain (${restrictToHost})`);
-    }
-  }
+//  if (restrictToHost) {
+//    if (!restrictToHost.endsWith(newCookie.domain) &&
+//        ("." + restrictToHost) !== newCookie.domain &&
+//       restrictToHost !== newCookie.domain) {
+//      throw new InvalidCookieDomainError(`Cookies may only be set ` +
+//          `for the current domain (${restrictToHost})`);
+//    }
+//  }

   // remove port from domain, if present.
   // unfortunately this catches IPv6 addresses by mistake
diff --git a/testing/marionette/driver.js b/testing/marionette/driver.js
--- a/testing/marionette/driver.js
+++ b/testing/marionette/driver.js
@@ -2638,9 +2638,9 @@ GeckoDriver.prototype.addCookie = functi
   let {protocol, hostname} = this.currentURL;

   const networkSchemes = ["ftp:", "http:", "https:"];
-  if (!networkSchemes.includes(protocol)) {
-    throw new InvalidCookieDomainError("Document is cookie-averse");
-  }
+//  if (!networkSchemes.includes(protocol)) {
+//    throw new InvalidCookieDomainError("Document is cookie-averse");
+//  }

   let newCookie = cookie.fromJSON(cmd.parameters.cookie);

diff --git a/testing/marionette/test_cookie.js b/testing/marionette/test_cookie.js
--- a/testing/marionette/test_cookie.js
+++ b/testing/marionette/test_cookie.js
@@ -190,10 +190,10 @@ add_test(function test_add() {
   });
   equal(2, cookie.manager.cookies.length);

-  Assert.throws(() => {
-    let biscuit = {name: "name3", value: "value3", domain: "domain3"};
-    cookie.add(biscuit, {restrictToHost: "other domain"});
-  }, /Cookies may only be set for the current domain/);
+//  Assert.throws(() => {
+//    let biscuit = {name: "name3", value: "value3", domain: "domain3"};
+//    cookie.add(biscuit, {restrictToHost: "other domain"});
+//  }, /Cookies may only be set for the current domain/);

   cookie.add({
     name: "name4",

【讨论】:

    【解决方案2】:

    为什么不让浏览器在添加 cookie 之前重定向到“example.com”。进入该域后,添加您从“example.com”获取的 cookie 值并刷新页面?

    根据项目跟踪器上的the answer by the team on this issue

    cookies 方法只对可见的 cookie 起作用 是唯一可以在所有环境中始终如一地工作的东西 浏览器。您看到的行为是预期的行为。

    【讨论】:

    • 您必须加载整个页面才能设置 cookie,这非常荒谬。如果您在多个域上有 cookie,则必须为每个域加载页面。
    • @speedplane:公平地说,对于编写 Selenium 的人来说,我不会认为这很荒谬——假设他们必须解决很多个别的浏览器特性。如果您的要求涉及更多,您总是可以在测试套件之外进行设置 - 例如创建 Firefox profile with cookies pre-configured 或将 cookie 文件传递​​给 PhantomJS 等。
    • 我同意。这太荒谬了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-09
    • 1970-01-01
    • 2013-05-08
    相关资源
    最近更新 更多