Python CGI 将正确的文本返回给curl,但浏览器显示尾随零

标签 python apache curl cgi

我用 Python 3 编写了这个简单的 CGI 应用程序:

#! /usr/bin/env python3.4

print("Content-type: text/html\n")

print("AAAA")
  • 如果我使用任何浏览器访问该 URL,我会看到一个显示以下内容的页面:“AAAA 0”。它在 Mac 上的 Firefox、Chrome 和 Safari 以及 iPhone 上的 Safari 中准确显示了这一点。将“AAAA”更改为其他内容会相应地更改所有浏览器中的输出,但尾随“0”始终保留在每个浏览器中。

  • 浏览器的“查看源代码”始终显示预期的字符串+换行符(当然,浏览器将其视为空格),后跟意外的 0:

    AAAA
    0
    
  • 直接从服务器的命令行 (./foo.py | hex) 执行它并使用十六进制编辑器查看输出会产生预期的输出:标题行和内容行,内容行为 41 41 41 0A(“AAAA\n”)

  • 从我的 Mac 笔记本电脑和 Linux 服务器的命令行中使用curl 同样会产生我期望的十六进制输出:41 41 41 41 0A

  • curl 在任何(经过测试的)平台上都不会显示尾随零。所有平台上的所有浏览器都会显示尾随零。

  • 如果我删除第二个“print”语句,只留下标题的一个“print”语句,则尾随“0”在所有浏览器中都会消失,只留下空白页,但如果我放置任何打印在标题打印之后的语句中,尾随零将出现在所有浏览器中,但不会出现在任何curl中。即使是空的“print()”也会产生一个空的第一行(我确定是换行符),然后在“查看源代码”的第二行上出现一个“0”。如果我添加更多打印行,插入正确的 doctype 和 html,则尾随零会显示在源中的 end-html 标记之后。如果我打印标题以外的任何内容,浏览器源代码中会显示尾随零。

  • 更改为Python3.2没有什么区别

  • 因此,为了让curl欺骗浏览器,我从几个浏览器中添加了“用户代理”。没有不同。 Curl 仍然总是显示我期望它显示的内容,并且所有浏览器仍然显示尾随零。

  • 重新输入简单代码(不是复制和粘贴)以确保没有不可见字符会产生相同的结果(以及 Python 源代码的十六进制 View 、在服务器上运行它的输出以及输出通过curl获得的所有内容均不显示多余字符)。

  • 这是使用 Apache+CGI 的共享主机,我没有更改任何 Apache 文件或创建任何 .htaccess 文件。

  • 我可以使用 mod_wsgi,如果这是用于生产,它工作得很好,但它是用于学习。我正在尝试教 children 如何使用低级 CGI,让他们手动从 ENV 变量中提取 GET 数据等,这样他们就可以在升级到更多预构建功能(cgi 模块,然后WSGI,然后是 Flask 等)重点是要了解发生了什么,但我不知道。

那么,有人可以告诉我这个最基本的网络应用程序中发生了什么吗?这个“0”来自哪里(成功状态代码?),为什么它显示在浏览器源代码中而不是在curl中?而且,最重要的是,我如何摆脱它?

更新: 仅当我的浏览器位于使用 ATT 的“LTE”传输数据的手机上,或任何通过与 ATT 的“LTE”网络共享访问网络的浏览器时,才会出现此问题。如果我 Handlebars 机走进屋子,它就会切换到康卡斯特/Wifi,刷新浏览器页面,“AAAA 0”就会变成“AAAA”。走出家门(超出 WiFi 范围),使用 LTE 刷新,“AAAA”又变回“AAAA 0”。笔记本电脑上的浏览器也会发生同样的情况。

所以,这是笔记本电脑连接时的 telnet 输出,并在所有浏览器中显示“AAAA 0”(我看不出问题,就像在curl中一样):

> telnet my.domain.com 80
Trying 100.99.98.97...
Connected to my.domain.com.
Escape character is '^]'.
GET /temp.py HTTP/1.0
Host: my.domain.com

HTTP/1.1 200 OK
Server: nginx
Date: Fri, 05 Sep 2014 23:28:10 GMT
Content-Type: text/html
Connection: close
Vary: Accept-Encoding

AAAA
Connection closed by foreign host.

最佳答案

结尾的“0”可能来自分块响应格式,但浏览器不应显示它。

如果您为响应添加了正确大小的“Content-Length” header ,那么它理应消失,因为 Apache 不会使用分块响应,因为它仅在长度未知的情况下使用。

如果您使用“telnet”连接到服务器并手动发出请求,您得到的完整输出是什么。

telnet server-hostname 80

然后输入:

GET /some/url HTTP/1.0
Host: virtual-hostname

之后有一个额外的空行。

关于Python CGI 将正确的文本返回给curl,但浏览器显示尾随零,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25677629/

相关文章:

python - 如何在 bash 中将前缀组合到 ls 的输出?

python - 已知类的属性如何在python中获取该类

tomcat 的 apache 代理保持活跃困惑

curl - 为什么curl 会截断这个查询字符串?

python - WSGI在应用程序的同一目录中找不到文件

php - Ubuntu 上的两个基本 PHP、Apache 问题

apache - 配置日志记录以捕获失败的用户登录尝试

perl - 使用 curl 解析 XML,获取图像的 URL 并下载它

linux - URL curl 时间

python - python 和 GUI 测试中的包内引用