是否完全有必要使用header('Content-Type:text/plain');?

83

我还没有看到带有或不带有这个头信息的区别。

6个回答

125

定义“必要”。

如果您希望浏览器知道文件的类型,则需要它。如果您没有覆盖它,PHP会自动将Content-Type头设置为text/html,因此您的浏览器将其视为不包含任何HTML的HTML文件。如果您的输出包含任何HTML,则会看到非常不同的结果。如果您发送以下内容:

<b><i>test</i></b>

Content-Type: text/html; charset=UTF-8 将在浏览器中以粗体和斜体显示文本:

✅ OK

Content-Type: text/plain; charset=UTF-8 将在浏览器中像这样显示:

<b><i>✅ OK</i></b>

简短版:如果你只输出不带像<>这样的特殊字符的普通文本,那么这并不是很重要,但这是错误的。


1
请问您能否提供关于PHP默认内容类型为text/html的声明来源?我并不反对这个说法,只是在寻找官方文件来证实。 - But those new buttons though..
10
搜索您的php.ini文件中的"default_mimetype"。文档中将说明"PHP内置默认值为text/html"。不确定为什么,但他们实际上没有在手册中声明它。 - Jeremy Logan
1
谢谢。我今天早些时候实际上发布了这个问题,并了解了这个设置。 - But those new buttons though..
2
这是危险的建议。它确实很重要。将用户控制的纯文本作为text/html发送跨站脚本攻击(XSS)。 - rjmunro
1
rjmunro 是正确的... 对于用户提供的数据,你确实需要关注。不过原始问题并没有明确说明这一点,所以我只是回答了问题。 - Jeremy Logan
请注意,如果您查看页面源代码,则两种情况下的内容相同。不同之处在于“content-type”标头会更改浏览器呈现源代码的方式。 - Flimm

69

PHP使用默认的Content-Type为text/html,这与text/plain非常相似,这就解释了为什么你看不到任何区别。

text/plain内容类型是必要的,如果您想原样输出文本(包括<>符号)。

例子:

header("Content-Type: text/plain");
echo "<b>hello world</b>";
// Displays in the browser: <b>hello world</b>

header("Content-Type: text/html");
echo "<b>hello world</b>";
// Displays in the browser with bold font: hello world

14
你的浏览器默认不使用text/html格式:PHP使用该格式。 - Miles
1
PHP默认使用Content-Type为"text/html"。 - Kristoffer Bohmann
2
那段代码有一个小错误。它可能在一个安静的HTTP客户端上工作,但是头部名称和它的值之间必须有一个空格: header("Content-Type: text/html"); - Angel
1
@Angel:已修复。谢谢。 - Kristoffer Bohmann
1
我不会说"text/html"和"text/plain"是“非常相似”的 - 它们非常不同。例如,如果您允许用户提供的文本进入一个带有text/html的文件中,并且您没有正确地将其编码为HTML实体,则会发生跨站点脚本攻击,即使通常不会访问该页面。攻击者只需要说服用户点击链接。 - rjmunro
请注意,如果您查看页面源代码,两种情况下的内容是相同的。不同之处在于content-type头部,它会改变浏览器呈现源代码的方式。 - Flimm

23

非常重要的一点是,您需要告诉浏览器您正在发送的数据类型。这种差异应该是显而易见的。尝试在您的浏览器中查看以下PHP文件的输出结果;

<?php
header('Content-Type:text/html; charset=UTF-8');
?>
<p>Hello</p>

您将看到:

你好

(请注意,如果在此情况下省略标题行 - text/html是PHP的默认设置,则将获得相同的结果)

将其更改为text/plain

<?php
header('Content-Type:text/plain; charset=UTF-8');
?>
<p>Hello</p>

你将看到:

<p>Hello</p>

为什么这很重要?如果你在一个PHP脚本中有类似以下的代码,例如被一个AJAX请求使用:

<?php
header('Content-Type:text/html; charset=UTF-8');
print "Your name is " . $_GET['name']

有人可以在他们的网站上放置一个链接到URL,例如http://example.com/test.php?name=%3Cscript%20src=%22http://example.com/eviljs%22%3E%3C/script%3E,如果用户点击了它,他们会将你网站上的所有信息暴露给放置该链接的人。如果你将文件作为text/plain提供,你是安全的。

请注意,这只是一个愚蠢的例子,更可能的是,恶意脚本标记会由攻击者添加到数据库中的字段或通过使用表单提交。


7

设置Content-Type头将影响Web浏览器对您的内容的处理方式。当大多数主流Web浏览器遇到text/plain的Content-Type时,它们会在浏览器窗口中呈现原始文本源(而不是呈现为HTML源)。这就是看到的区别。

<b>foo</b>

或者

foo

此外,当使用 XMLHttpRequest 对象时,您的 Content-Type 标头将影响浏览器如何序列化返回的结果。在 AJAX 框架 jQuery 和 Prototype 接管之前,AJAX 响应的常见问题是 Content-Type 设置为 text/html 而不是 text/xml。如果 Content-Type 是 text/plain,则可能会出现类似的问题。


1
如果您想用204:无内容的HTTP状态响应请求,Firefox浏览器会在控制台中抱怨“未找到元素”。 这是Firefox多年来一直存在但从未解决的Bug。 通过发送“Content-type: text/plain”头文件,您可以防止Firefox出现此错误。

0
不,不是这样的,这里有一个支持我的回答的例子——>明显的区别就在于当你使用HTTP压缩时,它允许你在数据从服务器传输到客户端的过程中进行压缩,而这种数据的类型会自动变为"gzip",告诉浏览器它得到了一个被压缩的数据,并且需要解压缩。这是一个类型真正重要的例子。

请问能否解释一下,如果我错了,因为我真的想纠正我的知识并且非常渴望学习。 - Ashish Agarwal
哦!!抱歉,我刚才忘了,但是你不觉得如果定义了类型,就可以压缩一些选择性的类型吗? - Ashish Agarwal
当然,你可以基于MIME类型进行选择性压缩(至少在Apache中可以),但是除非请求方无法处理,否则没有理由不压缩基于文本的实体。 - Jeremy Logan

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