Python SimpleCookie和JSON Value

时间:2016-07-05 14:40:11

标签: python python-3.x cookies httpcookie

当使用JSON字符串作为值时,我遇到了使用Python SimpleCookie的一些问题。

In [1]: from http.cookies import SimpleCookie

In [2]: cookie = SimpleCookie('x=1; json={"myVal":1}; y=2')

In [3]: cookie.keys()
Out[3]: dict_keys(['x'])

In [4]: cookie = SimpleCookie('x=1; y=2')

In [5]: cookie.keys()
Out[5]: dict_keys(['y', 'x'])

不仅缺少JSON字符串,而且之后的所有其他值都会丢失。我现在想知道这是否是一个与Python有关的错误,因为在cookie中使用这些字符都应该没问题?

2 个答案:

答案 0 :(得分:2)

目前,您尝试使用对象作为值,而不是该对象的JSON字符串表示形式。您需要在参数字符串中转义JSON字符串,如下所示:

>>> from http.cookies import SimpleCookie
>>> cookie = SimpleCookie(r'x=1; json="{\"myVal\":1}"; y=2')
                        # ^ note raw string    ^ and single backslashes
>>> cookie.keys()
dict_keys(['json', 'x', 'y'])

看起来奇怪的是,一个畸形的字符串尽可能地被悄悄地消耗掉,其余部分被抛弃了;我希望您输入ValueError或其他内容。 The parser只是停止并返回到目前为止结果与正则表达式匹配的内容。

鉴于Marius's answer,它似乎适用于3.3.2但在3.5.2中不起作用(对我而言,它看起来不应该在任何地方工作< / em>;一个隐式的JSON包导入?!)我去找它改变了。使用此脚本:

from http.cookies import SimpleCookie
import json
from sys import version

print(version)

cookie1 = SimpleCookie('x=1; json=json.dumps({"myVal":1}); y=2')
print('Marius  ', cookie1.keys(), repr(cookie1.get('json')), sep='\t')

cookie2 = SimpleCookie(r'x=1; json="{\"myVal\":1}"; y=2')
print('Jonathan', cookie2.keys(), repr(cookie2.get('json')), sep='\t')

cookie3 = SimpleCookie('x=1; json={"myVal":1}; y=2')
print('Bernhard', cookie3.keys(), repr(cookie3.get('json')), sep='\t')
Mac OS X上的

pyenv给出了3.3的以下结果:

3.3.0 (default, Jul  7 2016, 10:47:41)
[GCC 4.2.1 Compatible Apple LLVM 7.0.0 (clang-700.0.72)]
Marius      dict_keys(['x', 'y', 'json'])   <Morsel: json='json.dumps({'>
Jonathan    dict_keys(['x', 'y', 'json'])   <Morsel: json='{"myVal":1}'>
Bernhard    dict_keys(['x', 'y', 'json'])   <Morsel: json='{'>

3.3.1 (default, Jul  7 2016, 10:53:06)
[GCC 4.2.1 Compatible Apple LLVM 7.0.0 (clang-700.0.72)]
Marius      dict_keys(['json', 'x', 'y'])   <Morsel: json='json.dumps({'>
Jonathan    dict_keys(['json', 'x', 'y'])   <Morsel: json='{"myVal":1}'>
Bernhard    dict_keys(['json', 'x', 'y'])   <Morsel: json='{'>

3.3.2 (default, Jul  6 2016, 22:02:23)
[GCC 4.2.1 Compatible Apple LLVM 7.0.0 (clang-700.0.72)]
Marius      dict_keys(['json', 'y', 'x'])   <Morsel: json='json.dumps({'>
Jonathan    dict_keys(['json', 'y', 'x'])   <Morsel: json='{"myVal":1}'>
Bernhard    dict_keys(['json', 'y', 'x'])   <Morsel: json='{'>

# ...loses 'json'

3.3.3 (default, Jul  7 2016, 10:57:02)
[GCC 4.2.1 Compatible Apple LLVM 7.0.0 (clang-700.0.72)]
Marius      dict_keys(['x', 'y'])   None
Jonathan    dict_keys(['x', 'y', 'json'])   <Morsel: json='{"myVal":1}'>
Bernhard    dict_keys(['x', 'y'])   None

3.3.4 (default, Jul  7 2016, 10:59:21)
[GCC 4.2.1 Compatible Apple LLVM 7.0.0 (clang-700.0.72)]
Marius      dict_keys(['y', 'x'])   None
Jonathan    dict_keys(['y', 'x', 'json'])   <Morsel: json='{"myVal":1}'>
Bernhard    dict_keys(['y', 'x'])   None

3.3.5 (default, Jul  7 2016, 11:01:45)
[GCC 4.2.1 Compatible Apple LLVM 7.0.0 (clang-700.0.72)]
Marius      dict_keys(['y', 'x'])   None
Jonathan    dict_keys(['json', 'y', 'x'])   <Morsel: json='{"myVal":1}'>
Bernhard    dict_keys(['y', 'x'])   None

# ...and now 'y'!

3.3.6 (default, Jul  7 2016, 11:03:40)
[GCC 4.2.1 Compatible Apple LLVM 7.0.0 (clang-700.0.72)]
Marius      dict_keys(['x'])    None
Jonathan    dict_keys(['json', 'x', 'y'])   <Morsel: json='{"myVal":1}'>
Bernhard    dict_keys(['x'])    None

从那里看起来似乎很稳定:

3.4.4 (default, Jul  7 2016, 11:13:43)
[GCC 4.2.1 Compatible Apple LLVM 7.0.0 (clang-700.0.72)]
Marius      dict_keys(['x'])    None
Jonathan    dict_keys(['json', 'y', 'x'])   <Morsel: json='{"myVal":1}'>
Bernhard    dict_keys(['x'])    None

3.5.2 (v3.5.2:4def2a2901a5, Jun 26 2016, 10:47:25)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)]
Marius      dict_keys(['x'])    None
Jonathan    dict_keys(['x', 'json', 'y'])   <Morsel: json="{\"myVal\":1}">
Bernhard    dict_keys(['x'])    None

从3.3.6开始的版本显然是一个安全修复程序;见this bug report。这也适用于3.2.6,所以:

3.2.4 (default, Jul  7 2016, 11:05:33)
[GCC 4.2.1 Compatible Apple LLVM 7.0.0 (clang-700.0.72)]
Marius      dict_keys(['y', 'x', 'json'])   <Morsel: json='json.dumps({'>
Jonathan    dict_keys(['y', 'x', 'json'])   <Morsel: json='{"myVal":1}'>
Bernhard    dict_keys(['y', 'x', 'json'])   <Morsel: json='{'>

3.2.5 (default, Jul  7 2016, 11:07:15)
[GCC 4.2.1 Compatible Apple LLVM 7.0.0 (clang-700.0.72)]
Marius      dict_keys(['y', 'x', 'json'])   <Morsel: json='json.dumps({'>
Jonathan    dict_keys(['y', 'x', 'json'])   <Morsel: json='{"myVal":1}'>
Bernhard    dict_keys(['y', 'x', 'json'])   <Morsel: json='{'>

# ...loses 'y'?!

3.2.6 (default, Jul  7 2016, 11:09:00)
[GCC 4.2.1 Compatible Apple LLVM 7.0.0 (clang-700.0.72)]
Marius      dict_keys(['x', 'json'])    <Morsel: json='json.dumps({'>
Jonathan    dict_keys(['y', 'x', 'json'])   <Morsel: json='{"myVal":1}'>
Bernhard    dict_keys(['x', 'json'])    <Morsel: json='{'>

此行为与不同到3.3.6具有相同的错误修复!实际上,它会将Cookie中json的值设置为'{',并放弃该值的其余部分y

我的结论是:

  1. 我的版本适用范围更广;
  2. Marius的版本实际上并没有帮助OP,因为它与原始版本具有相同的密钥;和
  3. 在3.2和3.3中使用此功能发生了一些奇怪的事情!

答案 1 :(得分:0)

这包括'json'作为Python 3.3.2及更早版本中的密钥:

>>> import json
>>> from http.cookies import SimpleCookie
>>> cookie = SimpleCookie('x=1; json=json.dumps({"myVal":1}); y=2')
>>> cookie.keys()
dict_keys(['y', 'x', 'json'])

但是,该值可能与预期不符:

>>> print(cookie)
Set-Cookie: json=json.dumps({
Set-Cookie: x=1
Set-Cookie: y=2