什么是PHP头部?

17
我想知道PHP头文件是什么。我只在HTML完成时使用PHP, 我认为当输出是文本时必须发送text/html标头,然后从一个单独的脚本中发送image/jpeg标头,该脚本用作图像标记中的源文件,但是有人建议我去掉标头因为它们没有起到任何作用。
我这样做了,一切都和以前一样。这让我想知道:头文件是什么? 何时使用它们? (从HTML角度和其他一些(?)角度)以及为什么我可以删除我的标头?

6
你是说HTTP请求/响应头吗? - BoltClock
4
Content-TypeContent-Length是HTTP头。 - Femaref
我是否总是需要指定它们,还是只在特定条件下?如果我不提供头文件,浏览器会如何解释代码? - fast-reflexes
2
你的网络服务器通常会提供一组基本的头文件,例如缓存和内容类型。在正常使用中,你不需要特别提供头文件。 - Femaref
每当您需要它们用于特定目的时,使用不同的标头有各种原因。 - Rushyo
显示剩余2条评论
7个回答

29
有默认的header吗?如果我没有指定header,只是向浏览器发送一些PHP代码,它会应用哪个header?
有很多不同的HTTP头,意义各不相同。如果您没有设置它们,PHP将为重要的头提供默认值。
我认为你具体谈论的header是Content-Type。这告诉浏览器你发送的是什么类型的文件。如果你说text/html,它会尝试显示你提供给它的内容作为网页。如果你说application/pdf,它会尝试显示或下载它作为PDF文件。
PHP默认发送Content-Type: text/html。如果这就是你想要的,你根本不需要调用header('Content-Type: ...');。然而,如果你使用任何非ASCII Unicode字符,你可能希望将Content-Type设置为text/html;charset=something,其中something是你使用它们的编码(通常是utf-8)。否则,浏览器将不得不猜测,并可能猜错。常见的标记是执行相同操作的另一种方法;如果你想确保万无一失,你可以同时使用两种方法。
如果你将JPEG图像作为text/html进行服务,这正是“某人”撤销header()调用后会发生的情况,那么在浏览器中打开该图像的URL将尝试将二进制图像显示为HTML,这将在屏幕上给出一大堆垃圾。这真的很糟糕。然而在很多浏览器中,即使是这样的损坏JPEG,当你用<img src>标签引用它时,通常仍能正常工作。这是由于当你使用<img>时,浏览器知道它将会获取一张图片,并且忽略你说它实际上是HTML的说法。它接着要 "嗅探" 文件的内容来判断它是否看起来像一个 JPEG、GIF、PNG 或者其他它了解的图像类型,以便确定如何显示它。浏览器这么做是因为有太多写得很差的网站忘了发送头信息。哎呀!
所以在编写JPEG或其他非HTML类型时,一定要发送header('Content-Type: image/jpeg');对于HTML页面,通常可以不需要。

2
header('Content-Type', 'image/jpeg') 会导致错误。正确的语法是 header('Content-Type: image/jpeg') - Christopher Tarquini
谢谢,这是一次很好的解释。所以基本上,如果除了text/html之外还有其他类型的话,包含头信息总是更安全的选择,即使在某些情况下,如前面提到的图像情况,大多数浏览器可能已经处理正确了? - fast-reflexes
@Chris:谢谢,我有点Python的经验。@fast:是的,这对于“Content-Type”头是正确的。其他头部有不同的用途。(例如,“Content-Disposition: attachment”强制下载,“Location”重定向等) - bobince

11

HTTP头部不仅限于浏览器,它是HTTP协议的一部分。
请求页面或其他资源(如图像)将导致客户端(例如互联网浏览器)发送一个请求头。这可能包含语言(Accept-Language)的头信息。

HTTP请求的第一行格式为METHOD RESOURCE HTTP/VERSION,例如:GET /resource HTTP/1.0
HTTP/1.1需要Host-header。以下是HTTP/1.1请求示例:

GET / HTTP/1.1
Host: example.com

服务器至少会响应状态码: HTTP/1.1 200 OK
大多数服务器都会发送其他头部信息,常见的头部信息包括:Content-TypeDateServerContent-Length

以下是一个请求的示例(原始数据):

$ nc example.com 80
GET / HTTP/1.0

HTTP/1.1 200 OK
Date: Sat, 11 Sep 2010 19:12:13 GMT
Server: Apache
Last-Modified: Fri, 30 Jul 2010 15:30:18 GMT
ETag: "573c1-254-48c9c87349680"
Accept-Ranges: bytes
Content-Length: 596
Connection: close
Content-Type: text/html; charset=UTF-8

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<HTML>
<HEAD>
  <META http-equiv="Content-Type" content="text/html; charset=utf-8">
  <TITLE>Example Web Page</TITLE>
</HEAD> 
<body>  
<p>You have reached this web page by typing &quot;example.com&quot;,
&quot;example.net&quot;,&quot;example.org&quot
  or &quot;example.edu&quot; into your web browser.</p>
<p>These domain names are reserved for use in documentation and are not available 
  for registration. See <a href="http://www.rfc-editor.org/rfc/rfc2606.txt">RFC 
  2606</a>, Section 3.</p>
</BODY>
</HTML>
客户端(网络浏览器)是否解析标头取决于它自己。所有现代网络浏览器都会解析 Content-Type 标头,并使用它来确定如何显示资源(是HTML页面、图像、文本文件还是其他内容)。浏览器会忽略 Server 标头,服务器使用它来识别自己。但某些爬虫可能会将其用于统计。
引用自HTTP规范的一句话:
多个具有相同字段名的消息头字段可以在消息中存在,仅当该标头字段的整个字段值被定义为逗号分隔列表时才是如此(即,#(values))。必须能够将多个标头字段组合成一个“字段名称:字段值”对,而不改变消息的语义,方法是将每个后续字段值附加到第一个字段值上,每个字段值之间用逗号分隔。
这意味着多个 Content-Type 字段无效,行为未定义(尽管通常使用最后一个定义的字段值)。 此 Wikipedia 文章 包含带有描述的标头列表。

我明白了,谢谢。请解释一下“The Server is ignored by…”这句话,我没有完全理解。此外,这意味着我可以为每个输出发送多个不同的标头,但不能发送多个相同类型的标头,例如Content-Type。我必须为每个输出指定一个Content-Type,否则浏览器将不知道我期望它做什么,对吗? - fast-reflexes
"The Server是" 应该是 "The Server头部[字段]"。多个Content-Type`字段无效,请参见修改后的答案。 - Lekensteyn

4

头部信息不是PHP独有的,而是HTTP传输数据的一种方式。

在php中,header()函数允许你设置这些头部信息来适应你的代码使用情况。如果你的代码生成的是像jpg这样的图像而不是文本(比如HTML或JavaScript,需要被用户的浏览器解释),那么你就要将对应的头信息设置为image/jpeg。现在你可以将这个脚本用在其他地方,就像静态图像一样:

<img src="static.jpg"/>

现在,如果你想生成一个图像的缩略图,并希望动态访问它,你可以编写一个返回jpeg格式图像的php脚本,并像下面这样使用它:

<img src="thumb.php?s=64&name=static.jpg"/>"

thumb.php文件将根据静态图片static.jpg生成一个大小为64x64的缩略图(使用HTTP头信息Content-Type: image/jpeg)。

当然,这仅仅是header()函数的众多用途之一。欲了解更多信息,请参阅维基百科:超文本传输协议HTTP头信息列表,或者如果你足够勇敢,可以查看rfc文档


好的,你说“通常”PHP输入被认为是文本传递给浏览器?具体来说是text/html还是我错了?如果我只是将一些PHP发送到浏览器,它会如何解释它?另外,在上面的缩略图脚本中..我是否必须在那里使用一个image/jpeg头文件?因为在我的情况下,没有image/jpeg头文件也能正常运行,这让我感到疑惑... - fast-reflexes
好的,我明白了。我的意思是,如果我不提供头信息,我的服务器将如何将它发送到浏览器?这像HTML一样吗?另外,关于行为...是这种情况吗,因为thumb.php作为IMG标签的源提供,所以浏览器期望它作为图像出现,因此image/jpeg头信息不是必需的吗? - fast-reflexes
这取决于浏览器。有些浏览器会尝试检测传入数据的MIME类型,以确定如何处理它。其他浏览器会信任扩展名,例如JPEG图像数据的.jpg扩展名。IE和Firefox之间处理方式的不同实际上可能会导致一些烦人的问题,当开发人员没有适当测试时。 - Martijn Heemels
@Femaref 我有点困惑,假设我有一个名为something.php的文件,它的代码是 <?php header('Content-type:image/jpeg'); ?> <img src="kid.jpg">,如果我在浏览器上打开页面,我会得到一个破碎的小图标,而不是图片。为什么会这样呢?我认为img标签是HTML内容,但我改变了生成的内容类型为图像,不是吗? - user1906399
在浏览器中查看源代码。浏览器是为了易用性而设计的,并且也会对响应进行分析。如果它检测到响应明显不是“image/jpeg”,而是“text/html”,那么它将呈现它作为HTML(并添加任何缺失的标记)。 - Femaref
显示剩余2条评论

2
假设您所说的是header()函数。
这是一种向浏览器添加/更改HTTP标头的方法。
您可能需要在HTTP规范中查找这些标头的列表。
例如,您可能正在开发XML RSS Feed,因此需要将Content-Type更改为"text/xml"而不是默认值"text/html"。

2

头文件包含指令,用于告知浏览器以特定的方式呈现内容。例如,指定页面语言/字符集使用或告诉浏览器正在输出的数据是原始图像数据,因此要将其处理为图像(而不是常规文本),或者可以像header("Location: somepage.html")一样,让浏览器重定向到另一个页面。基本上,您会在正常的<head>...</head>标记中找到许多(以及更多)类似的内容。


好的,所以... 1. Headers 是浏览器特定的东西吗?2. 是否有默认的 header?如果我只是发送一些 PHP 到浏览器而没有指定 header.. 它会应用什么 header? - fast-reflexes
1
@fast-reflexes 头部信息并不是特指浏览器,而是HTTP协议的一部分。你知道,就像http://example.com - 它与ftp://example.com不同,因为内容是使用HTTP协议检索的。无论您使用浏览器、其他程序、类似cURL等的东西,都没有关系。它实际上与PHP无关,只涉及到PHP如何与Web服务器相关联。您可以使用Firebug或Chrome/Safari的检查器查看您的Web服务器发送的默认标头。 - JAL
响应头会发送给所有浏览器。如果没有指定任何设置(例如语言、字符集等),大多数浏览器会尝试使用“默认”设置。 - CrayonViolent
好的,所以有几种不同类型的头文件,这是HTTP协议的一部分,我明白了。这意味着我可以在开始实际输出之前从PHP发送多个头文件,对吗?但每个输出只能有一个Content头文件,是吗? - fast-reflexes
@fast-reflexes 是的,一个网站上典型的页面视图涉及到4-5个请求头和7-8个响应头。所以,是的,您可以发送尽可能多的请求头和响应头。但是,在您了解它们及其各自作用之前,我不建议这样做。而且,对于单个响应发送多个Content-Type头完全没有意义。这就像是说“这个文件既是html文本,又是jpeg图像,还是adobe flash视频!” - JAL

1

HTTP请求/响应头(在您的情况下是响应),是与响应一起发送的元数据(更准确地说,在数据之前)。

它可能包含诸如缓存指令、数据类型和大小、上次修改日期等信息。您可以在这里看到HTTP头列表。


0

我们应该区分传入头部(php作为Web服务器页面)和传出头部(php作为Web客户端使用类似cURL库的东西)。

头部实际上只是另一个名称-值对的集合,随着每个HTTP“请求”事务一起通过电线传输。正文是服务器发送回来的...东西,服务器还向客户端发送响应头。

每个头部中的名称-值对的含义由HTTP协议和其他标准定义,但客户端和服务器也可以将头部用于其他用途。

headers()用于设置响应头名称-值对,而getallheaders()用于检索发送到php服务器页面的请求头。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接