我想存储来自一个open-uri调用的cookie并将它们传递给下一个。我似乎找不到合适的文档来做这件事。如果你能告诉我正确的方法,我会很感激的。
注意:w3.org不是实际的网址,但它更短;假装饼干在这里很重要。
h1 = open("http://www.w3.org/")
h2 = open("http://www.w3.org/People/Berners-Lee/", "Cookie" => h1.FixThisSpot)
2天后更新:虽然这不是一个修辞问题,但我保证这是可能的。 翻滚后更新:看(答案),这是可能的。花了我很多时间,但它确实有效。
答案 0 :(得分:30)
我以为有人会知道,但我想这对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设置传递给下一个请求。
答案 1 :(得分:13)
您需要添加“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)
答案 2 :(得分:4)
感谢Matthew Schinckel您的回答非常有用。使用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
答案 3 :(得分:2)
根据您要完成的操作,请查看webrat。我知道它通常用于测试,但它也可以访问实时网站,它可以完成你的网页浏览器为你做的很多事情,比如在请求之间存储cookie并遵循重定向。
答案 4 :(得分:1)
如果您使用open-uri,则在提交请求时,在阅读和添加Cookie标头时,您必须通过解析元标头来推送自己的Cookie支持。考虑使用httpclient http://raa.ruby-lang.org/project/httpclient/或类似机械化的内容http://mechanize.rubyforge.org/,因为它们内置了cookie支持。
答案 5 :(得分:0)
有一个RFC 2109和RFC 2965 cookie jar实现可以在这里找到需要标准兼容的cookie处理。