怎么设置包含空格的cookie值?

cookie tornado python by Xudong Zhang @ 2015-10-21 22:08:01

我用tornado,想设置一个(name, “Zhang San”),得到invalid cookie, 如下:

  self.set_cookie('name', 'Zhang San')
File "/usr/local/lib/python3.4/dist-packages/tornado/web.py", line 524, in set_cookie
    raise ValueError("Invalid cookie %r: %r" % (name, value))
ValueError: Invalid cookie 'name': 'Zhang San'

查了下,似乎cookie不允许含有空格?


先看下tornado的web.set_cookie函数的头几行:

name = escape.native_str(name)
value = escape.native_str(value)
if re.search(r"[\x00-\x20]", name + value):
    # Don't let us accidentally inject bad stuff
    raise ValueError("Invalid cookie %r: %r" % (name, value))

那个re.search(r”[\x00-\x20]“)是导致一个异常的直接原因,空格的ascii码正好就是\x20.

那么为什么”\x00-\x20”是不允许的呢?

这是cookie的历史遗留问题,最开始netscape浏览器里就指定了只能用一些type string(可打印的字符,那些如TAB之类的就不是).现在各大浏览器如IE,chrome,firefox的具体行为方面还有一些差异.

RFC6265里面有这么一小段关于那些字符可用的描述:

%x21 / %x23-2B / %x2D-3A / %x3C-5B / %x5D-7E

也就是

0x21: !
0x23-2B: #$%&'()*+
0x2D-3A: -./0123456789: 
0x3C-5B: <=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[
0x5D-7E: ]^_`abcdefghijklmnopqrstuvwxyz{|}~

那么如果我实在要用其他字符如空格,怎么办呢?

基本方法都是将不在这个范围内的字符转义到这个范围内,可以用类似urlencode或者base64编码类似的方式.

如使用python的urllib.parse.quote来转义:

from urllib.parse import quote
...
self.set_cookie('name', quote('Zhang San'))
#quote('Zhang San')   == 'Zhang%20San'

对于中文字符quote会默认以utf-8编码然后再转义.

在javascript侧,直接用js-cookie获取值,貌似会自动转义过来.

Cookie.get('name');   //Get "Zhang San"
by Xudong Zhang @2015-09-23 14:13:59.495 +0800 CST


我来回答

Markdown格式技巧

  • 行尾添加2个空格或者添加一个空行就能换行
  • 斜体: *hello* 或者 _world_
  • 加粗: **hello** 或者 __world__
  • 代码块: 添加空行,然后代码缩进4个空格
  • 特殊字符: 用\避免转义;\*就是*本身
  • python: `__name__`可以以代码形式输出__name__
  • 一个简单的例子

切换到移动版