Ruby 的 open-uri 和 cookies

发布于 2024-08-03 23:09:49 字数 371 浏览 6 评论 0原文

我想存储来自一个 open-uri 调用的 cookie 并将它们传递给下一个调用。我似乎找不到合适的文档来执行此操作。如果您能告诉我正确的方法,我将不胜感激。
注意:w3.org 不是实际的网址,但它更短;假装饼干在这里很重要。

h1 = open("http://www.w3.org/")
h2 = open("http://www.w3.org/People/Berners-Lee/", "Cookie" => h1.FixThisSpot)

2 点后更新:虽然这并不是反问句,但我保证这是可能的。 风滚草之后更新:看(答案),这是可能的。我花了很长时间,但它有效。

I would like to store the cookies from one open-uri call and pass them to the next one. I can't seem to find the right docs for doing this. I'd appreciate it if you could tell me the right way to do this.
NOTES: w3.org is not the actual url, but it's shorter; pretend cookies matter here.

h1 = open("http://www.w3.org/")
h2 = open("http://www.w3.org/People/Berners-Lee/", "Cookie" => h1.FixThisSpot)

Update after 2 nays: While this wasn't intended as rhetorical question I guarantee that it's possible.
Update after tumbleweeds: See (the answer), it's possible. Took me a good while, but it works.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

天邊彩虹 2024-08-10 23:09:49

我以为有人会知道,但我想这通常不是用 open-uri 完成的。
这是一个丑陋的版本,既不检查隐私、过期、正确的域名,也不检查正确的路径:

h1 = open("http://www.w3.org/")
h2 = open("http://www.w3.org/People/Berners-Lee/",
          "Cookie" => h1.meta['set-cookie'].split('; ',2)[0])

是的,它有效。不,它不漂亮,也不完全符合建议,也不处理多个 cookie(按原样)。

显然,HTTP 是一个非常简单的协议,open-uri 可以让您充分利用它。我想我真正需要知道的是如何从 h1 请求中获取 cookie,以便可以将其传递给 h2 请求(这部分我已经知道并展示了)。令人惊讶的是,有多少人基本上想通过告诉我不要使用 open-uri 来回答,而其中只有一个人展示了如何将一个请求中设置的 cookie 传递到下一个请求。

I thought someone would just know, but I guess it's not commonly done with open-uri.
Here's the ugly version that neither checks for privacy, expiration, the correct domain, nor the correct path:

h1 = open("http://www.w3.org/")
h2 = open("http://www.w3.org/People/Berners-Lee/",
          "Cookie" => h1.meta['set-cookie'].split('; ',2)[0])

Yes, it works. No it's not pretty, nor fully compliant with recommendations, nor does it handle multiple cookies (as is).

Clearly, HTTP is a very straight-forward protocol, and open-uri lets you at most of it. I guess what I really needed to know was how to get the cookie from the h1 request so that it could be passed to the h2 request (that part I already knew and showed). The surprising thing here is how many people basically felt like answering by telling me not to use open-uri, and only one of those showed how to get a cookie set in one request passed to the next request.

最佳男配角 2024-08-10 23:09:49

您需要添加一个“Cookie”标头。

我不确定 open-uri 是否可以做到这一点,但可以使用 Net::HTTP 来完成。

# Create a new connection object.
conn = Net::HTTP.new(site, port)

# Get the response when we login, to set the cookie.
# body is the encoded arguments to log in.
resp, data = conn.post(login_path, body, {})
cookie = resp.response['set-cookie']

# Headers need to be in a hash.
headers = { "Cookie" => cookie }

# On a get, we don't need a body.
resp, data = conn.get(path, headers)

You need to add a "Cookie" header.

I'm not sure if open-uri can do this or not, but it can be done using Net::HTTP.

# Create a new connection object.
conn = Net::HTTP.new(site, port)

# Get the response when we login, to set the cookie.
# body is the encoded arguments to log in.
resp, data = conn.post(login_path, body, {})
cookie = resp.response['set-cookie']

# Headers need to be in a hash.
headers = { "Cookie" => cookie }

# On a get, we don't need a body.
resp, data = conn.get(path, headers)
人海汹涌 2024-08-10 23:09:49

谢谢马修·申克尔,你的回答非常有用。使用 Net::HTTP 我成功了

        # Create a new connection object.
          site = "google.com"
          port = 80
          conn = Net::HTTP.new(site, port)

        # Get the response when we login, to set the cookie.
        # body is the encoded arguments to log in.
          resp, data = conn.post(login_path, body, {})
          cookie = resp.response['set-cookie']

        # Headers need to be in a hash.
          headers = { "Cookie" => cookie }

        # On a get, we don't need a body.
          resp, data = conn.get(path, headers)

          puts resp.body

Thanks Matthew Schinckel your answer was really useful. Using Net::HTTP I was successful

        # Create a new connection object.
          site = "google.com"
          port = 80
          conn = Net::HTTP.new(site, port)

        # Get the response when we login, to set the cookie.
        # body is the encoded arguments to log in.
          resp, data = conn.post(login_path, body, {})
          cookie = resp.response['set-cookie']

        # Headers need to be in a hash.
          headers = { "Cookie" => cookie }

        # On a get, we don't need a body.
          resp, data = conn.get(path, headers)

          puts resp.body
当爱已成负担 2024-08-10 23:09:49

根据您想要实现的目标,请查看 webrat。我知道它通常用于测试,但它也可以访问实时网站,并且它可以完成您的网络浏览器可以为您做的很多事情,例如在请求之间存储 cookie 并遵循重定向。

Depending on what you are trying to accomplish, check out webrat. I know it is usually used for testing, but it can also hit live sites, and it does a lot of the stuff that your web browser would do for you, like store cookies between requests and follow redirects.

染年凉城似染瑾 2024-08-10 23:09:49

如果您使用 open-uri,则必须在读取时解析元标头并在提交请求时添加 cookie 标头来滚动自己的 cookie 支持。考虑使用 httpclient http://raa.ruby-lang.org/project/httpclient/ 或类似 mechanize 的东西 http://mechanize.rubyforge.org/ 因为它们内置了 cookie 支持在。

you would have to roll your own cookie support by parsing the meta headers when reading and adding a cookie header when submitting a request if you are using open-uri. Consider using httpclient http://raa.ruby-lang.org/project/httpclient/ or something like mechanize instead http://mechanize.rubyforge.org/ as they have cookie support built in.

可是我不能没有你 2024-08-10 23:09:49

对于需要符合标准的 cookie 处理的用户,可以在此处找到 RFC 2109 和 RFC 2965 cookie jar 实现。

https://github.com/dwaite/cookiejar

There is a RFC 2109 and RFC 2965 cookie jar implementation to be found here for does that want standard compliant cookie handling.

https://github.com/dwaite/cookiejar

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文