在 Python cgi 中设置浏览器 cookie 时出现问题

Problems setting browser cookies in Python cgi

我正在开发一个网络工具,但在设置 cookie 时遇到了一些问题。 20 年前,我曾经在 Perl 中这样做过,我很震惊地发现在 2017 年似乎没有一种清晰干净的方法来处理 Python 的 cookie!我认为简单快捷的事情花了一整天的时间。我尝试过手动设置 cookie,使用请求模块,以及我在 Stack Overflow 上找到的大量部分代码示例。我到处看,文档很差,没有完整的工作示例,或者答案很旧。

我正在使用 Python 创建一个 cgi 脚本。在脚本的登录页面上,我有 print "Content-type: text/html\r\n" 以便在网页上显示文本框和 select 菜单。当用户点击提交时,我有一个验证步骤,如果有错误,需要在页面上打印一些东西。如果没有错误,我需要脚本来加载新页面并设置 cookie。

这是我用来设置 cookie 的代码:

    #!C:\Python27\python.exe -u

    import Cookie
    c = Cookie.SimpleCookie()
    c['id'] = '12345'
    c['score'] = '8.76'
    c['page'] = '3'
    print "Content-type: text/html %s;\r\n" % (c)
    print ""
    print c

问题是:

  1. 当我在 运行 上面的代码本身之后在 Firefox 中检查 "Show Cookies" 时,上面显示的三个 c 值中只有两个被存储为 cookie。
  2. 我在脚本中登陆的页面在顶部显示 Content-type: text/html Set-Cookie: score=8.76 Set-Cookie: id=12345 Set-Cookie: page=3 ;,这是由于使用 print 语句设置 cookie 并再次发送 Content-type。发生这种情况时,我的浏览器中不会存储任何 cookie。只有在 headers.
  3. 中还没有 Content-type: text/html 时才会存储 Cookie

有没有一种方法可以从我的脚本中设置 cookie 而无需将 Content-type: text/html 的另一个副本打印到浏览器?

我还需要一种方法来在用户在工具中移动时无缝更新 cookie。例如,当他们点击下一页时,cookie 将更新为下一页。

我在 Windows 10 上使用 Python 2.7,并使用 Firefox 作为我的测试浏览器。

我已经设法解决了这两个问题。

问题 #1:上面显示的三个 c 值中只有两个存储为 cookie。

解决方案:我设置了 cookie,以便在一个 cookie 中传递三个值。例如:

import Cookie
c = Cookie.SimpleCookie()
c['id'] = '12345|score=8.76|page=3'

# Output the HTTP message containing the cookie BEFORE Content-type text/html!
print c
print "Content-type: text/html\r\n"

问题 #2:网页输出中的额外 Content-type: text/html header:

解决方案:每次服务器响应来自浏览器的 GET 或 POST 事件时,设置 cookie 需要成为 http 响应中发生的第一件事。我不得不重新排序脚本中使用的逻辑,以确保始终如此。对于每个 http 响应,在处理 cookie 之前,不会通过 Content-type: text/html 向浏览器打印任何内容。