【问题标题】:How to set Cookies at Http Get method using Java如何使用 Java 在 Http Get 方法中设置 Cookie
【发布时间】:2011-03-16 00:23:27
【问题描述】:

我想使用 cookie 进行手动 GET 以下载和解析网页。我需要提取安全令牌,以便在论坛上发帖。我已完成登录,已阅读响应并提取了 cookie(3 对 (name,value) )。然后我写了这样的包含 cookie 的字符串:

CookieString="name1=value1; name2=value2; name3=value3"

然后我执行以下操作

HttpURLConnection connection
connection = (HttpURLConnection)(new URL(Link).openConnection());
connection.setRequestMethod("GET");
connection.setRequestProperty("Connection", "Keep-Alive");
connection.setRequestProperty("Cookie", CookieString );
connection.connect();

然后我阅读了该页面,但它显示我没有登录论坛。我做错了什么?

编辑:我知道如果我想发帖,我必须提取安全令牌。我的思路是,为了提取它,我需要获取这个特定页面。但是要使安全令牌成为隐藏字段,我必须在线,因此我需要 cookie。但是当我 GET 页面并如上所述设置 cookie 时,我将页面作为访客获取,这表明我不在线并且安全令牌的值是访客,这对我没有用。我会检查你给我的链接,希望能找到解决办法。

【问题讨论】:

    标签: java http cookies get forum


    【解决方案1】:

    可以肯定的是,您应该从响应的 Set-Cookie 标头中收集 cookie。要在后续请求中将它们发送回来,您应该使用URLConnection#addRequestProperty() 将它们一一设置。

    基本上:

    // ...
    
    // Grab Set-Cookie headers:
    List<String> cookies = connection.getHeaderFields().get("Set-Cookie");
    
    // ...
    
    // Send them back in subsequent requests:
    for (String cookie : cookies) {
        connection.addRequestProperty("Cookie", cookie.split(";", 2)[0]);
    }
    
    // ...
    

    split(";", 2) 用于摆脱与服务器端无关的 cookie 属性,例如 expirespath 等。

    对于更方便的 HTTP 客户端,我建议查看Apache HttpComponents Client。它可以更透明地处理所有 cookie 内容。

    另见:


    更新:根据 cmets,这不是 cookie 问题。错误的请求令牌意味着服务器内置了 CSRF/bot 预防(以防止像你这样的人)。您需要从带有表单的请求页面中提取令牌作为隐藏输入字段,并将其作为请求参数重新发送。 Jsoup 可能有助于提取所有(隐藏的)输入字段。不要忘记传递您想以编程方式“按下”的按钮的名称-值对。另请参阅上述链接以获取更多提示。

    将来,您真的应该更清楚您检索到的确切错误,而不是胡乱猜测。复制粘贴确切的错误信息等等。

    【讨论】:

    • 这就是我所做的,但它不起作用。我从响应的 Set-Cookie 标头中读取了 cookie。我曾经将它们与 setRequestProperty 一起设置。我一一尝试了 addRequestProperty 但结果是一样的。我找不到我做错了什么。如果可能的话,我宁愿避免使用第 3 方库。
    • 那么问题出在其他地方。网址是什么?像 Fiddler 这样的 HTTP 跟踪器工具是怎么说的?
    • 网址是一个vbulletin论坛的帖子回复页面。奇怪的是,当我使用带有 POST 方法的同一链接中的 cookie 来发布回复时,响应是一个页面,显示我没有有效的安全令牌,但它看到我在线,因此饼干工作。当我尝试使用相同的 cookie 获取相同的页面以提取安全令牌时,它要求我登录。我将安装 fiddler,看看它是如何工作的,然后会回复你。如果你有任何想法请告诉我。
    • FWIW,对于在 Android 上工作的人,我最近尝试将多个 cookie 附加到 UrlConnection 并发现 addRequestProperty() 实际上并没有添加多个同名标题。这种观察可能是错误的,但我能让服务器识别我的多个 cookie 的唯一方法是将它们加入一个 String,并用 ; 分隔它们。然后将StringaddRequestProperty()/setRequestProperty() 设置为“Cookie”标头,如上所示。我似乎发现了关于 addRequest...setRequest... 实际做什么的相互矛盾的信息。
    • 试过了,我相信cookie.split(";", 1)[0] 应该是cookie.split(";", 2)[0](限制参数表示要返回的片段数,其中最后的片段会自动占用字符串的剩余部分)。
    【解决方案2】:

    假设 cookie 值不是硬编码而是从先前的请求中获得的,那么使用 @987654321@ 类可能是最简单的。

    CookieHandler.setDefault(new CookieManager());
    

    然后您的HttpURLConnection 将自动保存它收到的所有 cookie,并将它们与下一个请求一起发送回同一主机。

    【讨论】:

      【解决方案3】:
      // Grab Set-Cookie headers:
      List<String> cookies = connection.getHeaderFields().get("Set-Cookie");
      
      // ...
      
      // Send them back in subsequent requests:
      for (String cookie : cookies) {
          connection.addRequestProperty("Cookie", cookie.split(";", 1)[0]);
      }
      

      上面的代码可以发送多个 cookie,只需使用 setRequestProperty 而不是 addRequestProperty。工作代码是:

      // Grab Set-Cookie headers:
      List<String> cookies = connection.getHeaderFields().get("Set-Cookie");
      
      // ...
      
      // Send them back in subsequent requests:
      for (String cookie : cookies) {
          connection.setRequestProperty("Cookie", cookie.split(";", 1)[0]);
      }
      

      【讨论】:

        猜你喜欢
        • 2015-11-24
        • 2014-01-04
        • 2012-03-13
        • 2012-01-16
        • 1970-01-01
        • 2016-12-28
        • 2016-03-02
        • 1970-01-01
        • 2016-07-19
        相关资源
        最近更新 更多