【问题标题】:Why do use `\n` in CGI script while printing header?为什么在打印标题时在 CGI 脚本中使用 `\n`?
【发布时间】:2016-11-25 21:45:39
【问题描述】:

在 CGI 脚本中,我们使用的程序顶部是:

print "Content-type: text/html\n\n";

如果不使用\n,它将不会执行。但是,在 HTML 正文中,我们不使用\n,因为\n 没有任何意义,对于新行我们使用<br> 标签。

为什么\n 必须在标题行中?

【问题讨论】:

  • 这与Perl无关,与HTTP spec有关
  • 顺便说一句,所有框架都有一种明智的方式来创建标题,而无需输入所有这些,即使是 CGI $q->header;

标签: perl http cgi


【解决方案1】:

CGI脚本的第一行必须是Content-Type: text/html,打印语句必须有2个\n字符:

  • 一个终止当前行。
  • 第二个在 CGI 头和数据之间产生空行。

    print "Content-Type: text/html\n\n";

【讨论】:

  • "Content-Type" 只是 CGI 脚本可以提交的众多 HTTP 标头之一,在可能的标头中,它并不一定要先出现,只要它出现在空行和 HTTP 消息正文。
【解决方案2】:

Content-type: text/html 是 HTTP 标头,而不是 HTML。用于检测 HTTP 标头的结尾必须是一个空行。第一个 \n 表示当前行的结尾,第二个 \n 表示新的空行。

【讨论】:

  • 其实是一个CGI头。服务器接收 CGI 响应并将其转换为 HTTP 响应。这包括将裸换行符转换为回车符 - HTTP 所需的换行符对。
【解决方案3】:

任何 HTTP 响应(无论内容是否为 HTML)都必须以状态码(通常由 Web 服务器添加,而不是您的 CGI 程序添加)、Content-Type 标头以及可选的一个或多个开头额外的标题。每个标题必须在单独的行上(即以\n 结尾)。发送完所有 headers 后,使用空行表示 headers 已完成,响应的正文如下。

标头完成后,然后HTML(或其他)正文开始,\n 不再具有任何实际意义,因为 HTML 在呈现内容时会忽略它。

【讨论】:

  • HTTP 用 CRLF 分隔标题行。大多数 CGI 程序输出的 CGI 标头是供服务器破坏并扩展为正确的形式。
【解决方案4】:

注意:“CRLF”等同于“\r\n”(即carriage return 后跟line feed newline

对于每条 HTTP 消息,每个 Header field 后面必须跟一个 CRLF,然后,所有的标头字段一起跟在另一个 CRLF(一个空行)as specified in RFC 2616

所以,你可能会问,如果在 HTTP 标头之后需要两个 CRLF,我们为什么不直接编写 CGI 脚本,代码如下:

print "Content-type: text/html\r\n\r\n";

我们很好,这样的代码会运行得很好!然而,由于像 Linux 和 macOS 这样的基于 Unix 的系统使用 LF 而不是 CRLF,所以 CGI 服务器被定制为与 Unix 环境配合得很好,并且通过将 CGI Header 中的每个 \n 转换为 @987654328 来实现@HTTP Header,在RFC 3875中指定。

利用当 CGI 脚本运行并将 CGI 标头转换为 HTTP 标头时服务器上发生的 LF -> CRLF 转换,我们可以运行:

print "Content-type: text/html\n\n";

只要我们的 CGI 服务器按照 RFC 规范运行,这两个 LF 字符就会在发送 HTTP 消息时呈现为两个 CRLF。

考虑到 LF -> CRLF 替换的这一原则,我们可以尝试其他可能性,例如让 CGI 服务器仅用 CRLF 替换第一个 LF:

print "Content-type: text/html\n\r\n";

或者只是第二个 LF:

print "Content-type: text/html\r\n\n";

两者都可以!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-20
    • 1970-01-01
    • 1970-01-01
    • 2021-08-22
    • 2016-02-18
    • 2018-11-08
    相关资源
    最近更新 更多