Python aiohttp.ClientSession不使用';到期日';钥匙
我有一个虚拟服务器,它用Python aiohttp.ClientSession不使用';到期日';钥匙,python,cookies,python-asyncio,aiohttp,Python,Cookies,Python Asyncio,Aiohttp,我有一个虚拟服务器,它用Set cookie发送cookie,我用aiohttp.ClienSession调用它 当我发送一个带有名称和值的简单cookie时,会话将其存储在cookie jar中。 但是,如果我添加一个expires键,那么cookie就根本不会被存储 此行为仅在expires键时发生,其他标准键不发生。 另外,当我使用requests.Session时,cookie被正确存储 我发送饼干的方式有问题吗 以下是服务器的代码: import flask app = flask
Set cookie
发送cookie,我用aiohttp.ClienSession
调用它
当我发送一个带有名称和值的简单cookie时,会话将其存储在cookie jar中。
但是,如果我添加一个expires
键,那么cookie就根本不会被存储
此行为仅在expires
键时发生,其他标准键不发生。
另外,当我使用requests.Session
时,cookie被正确存储
我发送饼干的方式有问题吗
以下是服务器的代码:
import flask
app = flask.Flask(__name__)
@app.route("/cookie/<name>/<value>")
def send_cookie(name, value):
cookie = f"{name}={value}"
response = flask.Response(status=200, headers={"Set-Cookie": cookie})
return response
@app.route("/cookie/expires/<name>/<value>")
def send_expiring_cookie(name, value):
cookie = f"{name}={value}; expires=Wed, 15 Jan 2020 09:45:07 -0000"
response = flask.Response(status=200, headers={"Set-Cookie": cookie})
return response
app.run("localhost")
使用请求。会话
:
import asyncio as aio
import aiohttp
async def main():
async with aiohttp.ClientSession() as session:
response = await session.get("http://localhost:5000/cookie/hello/world")
print(session.cookie_jar._cookies)
# defaultdict(<class 'http.cookies.SimpleCookie'>, {'localhost': <SimpleCookie: hello='world'>})
async with aiohttp.ClientSession() as session:
response = await session.get("http://localhost:5000/cookie/expires/hello/world")
print(session.cookie_jar._cookies)
# defaultdict(<class 'http.cookies.SimpleCookie'>, {})
loop = aio.get_event_loop()
loop.run_until_complete(main())
import requests
with requests.Session() as session:
session.get("http://localhost:5000/cookie/hello/world")
print(session.cookies)
# <RequestsCookieJar[<Cookie hello=world for localhost.local/cookie/hello>]>
with requests.Session() as session:
session.get("http://localhost:5000/cookie/expires/hello/world")
print(session.cookies)
# <RequestsCookieJar[<Cookie hello=world for localhost.local/cookie/expires/hello>]
导入请求
将requests.Session()作为会话:
会话。获取(“http://localhost:5000/cookie/hello/world")
打印(会话.cookies)
#
将requests.Session()作为会话:
会话。获取(“http://localhost:5000/cookie/expires/hello/world")
打印(会话.cookies)
#首先,感谢您为这个问题提供了这么好的工作示例
我通过对expires字段中的空格进行转义,使您的解决方案能够存储cookie,如下所示:
import re
import flask
app = flask.Flask(__name__)
@app.route("/cookie/<name>/<value>")
def send_cookie(name, value):
cookie = f"{name}={value}"
response = flask.Response(status=200, headers={"Set-Cookie": cookie})
return response
@app.route("/cookie/expires/<name>/<value>")
def send_expiring_cookie(name, value):
exp_date = re.escape("Wed, 15 Jan 2020 09:45:07 -0000")
cookie = f"{name}={value}; expires={exp_date}"
response = flask.Response(status=200, headers={"Set-Cookie": cookie})
return response
app.run("localhost")
重新导入
进口烧瓶
app=烧瓶。烧瓶(\uuuuu名称\uuuuuuu)
@应用程序路径(“/cookie/”)
def发送_cookie(名称、值):
cookie=f“{name}={value}”
response=flask.response(状态=200,标题={“设置Cookie”:Cookie})
返回响应
@app.route(“/cookie/expires/”)
def发送\过期\ cookie(名称、值):
exp_date=re.escape(“星期三,2020年1月15日09:45:07-0000”)
cookie=f“{name}={value};expires={exp\u date}”
response=flask.response(状态=200,标题={“设置Cookie”:Cookie})
返回响应
app.run(“localhost”)
我认为问题在于aiohttp解析日期的方式。我不知道他们声称什么应该起作用,但它肯定是使用正则表达式来解析日期的,所以它需要转义是有意义的。未设置cookie的原因是未成功解析它。
aiohttp
模块依赖于标准库及其SimpleCookie
类中的http.cookies
当响应到达时,将检查其标题是否有Set Cookie
键,并使用与其关联的值来实例化SimpleCookie
。
后者有一个load
方法,该方法解析cookie字符串并提取cookie信息。
为了实现这一点,cookie字符串与在同一模块第434行(在标签v3.7.2
上)定义的正则表达式\u CookiePattern
匹配:
此模式实现(以一种有点复杂且不绝对准确但仍然很短的方式)由指定的日期格式
因此,我的cookie(其expires
字段为expires=Wed,2020年1月15日09:45:07-0000
)自然会被忽略,因为时区表示为-0000
,而预期为GMT
。
顺便说一句,我是这么说的:
格林尼治标准时间
格林威治标准时间。HTTP日期总是以GMT表示,而不是以本地时间表示
结论是我的曲奇简直是畸形的。
用GMT
替换-0000
也就不足为奇了。嘿,非常感谢你的回答!是的,这肯定是由于cookie的解析方式造成的,但更糟糕的是:如果密钥是Expires
且大写E
,它就可以工作了。。。我来看看。如果我没有弄错的话,aiohttp
使用来自http.cookies
的cookies,我猜请求
使用了不同的东西。我会通知你的!
_CookiePattern = re.compile(r"""
\s* # Optional whitespace at start of cookie
(?P<key> # Start of group 'key'
[""" + _LegalKeyChars + r"""]+? # Any word of at least one letter
) # End of group 'key'
( # Optional group: there may not be a value.
\s*=\s* # Equal Sign
(?P<val> # Start of group 'val'
"(?:[^\\"]|\\.)*" # Any doublequoted string
| # or
\w{3},\s[\w\d\s-]{9,11}\s[\d:]{8}\sGMT # Special case for "expires" attr
| # or
[""" + _LegalValueChars + r"""]* # Any word or empty string
) # End of group 'val'
)? # End of optional value group
\s* # Any number of spaces.
(\s+|;|$) # Ending either at space, semicolon, or EOS.
""", re.ASCII | re.VERBOSE) # re.ASCII may be removed if safe.
\w{3},\s[\w\d\s-]{9,11}\s[\d:]{8}\sGMT