问题描述
.它将关闭和打开标签重写为长短形式,但也很容易修复了前导和尾随空格、Unicode 和 UTF-x BOM 问题:
在整个包含或项目目录中使用是安全的.
?>
后的空格如果在后面提到了错误源那么这是写出一些空白或原始文本的地方.此时
通常建议,特别是对于新手,尾随 ?>
避免了这些案例中的一小部分.(通常 include()d
脚本是罪魁祸首.)
提到的错误源为第 0 行未知"
如果没有错误源,通常是
- 偶尔是
gzip
流编码设置. - 但它也可以是任何双重加载的
extension=
模块生成隐式
之前的错误消息
如果另一个
在这种情况下,您需要避开错误,延迟语句执行,或使用例如抑制消息 或 -当两者都不会妨碍以后的调试时.
没有错误信息
如果您根据 禁用了
error_reporting
或 display_errors
,那么不会出现警告.但是忽略错误不会使问题解决离开.过早输出后仍然无法发送Header.
因此,当 header("Location: ...")
重定向以静默方式失败时,这是非常建议探测警告.使用两个简单的命令重新启用它们在调用脚本之上:
error_reporting(E_ALL);ini_set(display_errors", 1);
或者 set_error_handler("var_dump");
如果其他方法都失败了.
说到重定向头,你应该经常使用这样的习惯用法这是最终代码路径:
exit(header("Location:/finished.html"));
最好是一个实用函数,它打印用户消息在 header()
失败的情况下.
输出缓冲作为一种解决方法
输出缓冲是缓解此问题的解决方法.它通常工作可靠,但不应该替代适当的应用程序结构并将输出与控制分离逻辑.它的实际目的是尽量减少到网络服务器的分块传输.
尽管如此,设置还是有帮助的.在 甚至 上现代 FPM/FastCGI 设置.
启用它将允许它同样可以调用ob_start();在调用脚本之上.然而,由于多种原因,它不太可靠:
因此两种方法都可能变得不可靠 - 特别是在两者之间切换时开发设置和/或生产服务器.这就是为什么输出缓冲是被广泛认为只是一个拐杖/严格来说是一种解决方法.
但它在另一台服务器上工作!?
如果您之前没有收到标题警告,那么 来探测是否仍然可以...发送标头.这对有条件地打印很有用信息或应用其他回退逻辑.
if (headers_sent()) {die("重定向失败.请点击此链接:<a href=...>");}别的{退出(标题(位置:/user.
有用的后备解决方法是:
HTML
标签
如果您的应用程序在结构上难以修复,那么一个简单的(但有点不专业)允许重定向的方法是注入 HTML
标签.可以通过以下方式实现重定向:
或短暂延迟:
当在
部分之后使用时,这会导致无效的 HTML.大多数浏览器仍然接受它.
JavaScript 重定向
作为替代,JavaScript 重定向可用于页面重定向:
location.replace(target.html");
虽然这通常比
<meta>
解决方法更符合 HTML,它导致对支持 JavaScript 的客户端的依赖.
然而,当真正的 HTTP header() 时,这两种方法都可以接受调用失败.理想情况下,您总是将此与用户友好的消息结合起来,并且可点击链接作为最后的手段.(例如,PECL 扩展可以.)
为什么setcookie()
和 session_start()
也会受到影响
setcookie()
和 session_start()
都需要发送一个 Set-Cookie:
HTTP 头.因此适用相同的条件,并且将生成类似的错误消息用于过早的输出情况.
(当然,它们还受到浏览器中禁用的 cookie 的影响甚至代理问题.会话功能显然也依赖于免费磁盘空间和其他
更多链接
- Google 提供了一个.
- 当然,也已在 Stack Overflow 上进行了介绍.
- WordPress 常见问题解答解释了如何解决标题已发送警告问题?一种通用的方式.
- Adobe 社区:
- Nucleus 常见问题解答:什么是页面标题已发送"?是什么意思?
- 更详尽的解释之一是HTTP 标头和 (互联网档案链接).它详细介绍了 HTTP,并提供了一些重写脚本的指南.
When running my script, I am getting several errors like this:
The lines mentioned in the error messages contain header() and calls.
What could be the reason for this? And how to fix it?
No output before sending headers!
Functions that send/modify HTTP headers must be invoked before any output is made.Otherwise the call fails:
Some functions modifying the HTTP header are:
- /
- /
- /
Output can be:
Unintentional:
- Whitespace before
<? or after
?>
- The UTF-8 Byte Order Mark specifically
- Previous error messages or notices
- Whitespace before
Intentional:
print
,echo
and other functions producing output- Raw
<html>
sections prior<? code.
Why does it happen?
To understand why headers must be sent before output it's necessaryto look at a typical HTTPresponse.
HTTP/1.1 200 OK
Powered-By:
The page/output always follows the headers.
When print, echo
, <html>
) it willflush all collected headers. Afterward it can send all the outputit wants. But sending further HTTP headers is impossible then.
How can you find out where the premature output occurred?
The header()
warning contains all relevant information tolocate the problem cause:
Here "line 100" refers to the script where the header()
invocation failed.
The "output started at" note within the parenthesis is more significant.It denominates the source of previous output. In this example, it's auth.and line
52
. That's where you had to look for premature output.
Typical causes:
Print, echo
Intentional output from
print
andecho
statements will terminate the opportunity to send HTTP headers. The application flow must be restructured to avoid that. Use and templating schemes. Ensureheader()
calls occur before messagesare written out.Functions that produce output include
print
,echo
,printf
,vprintf
trigger_error
,ob_flush
,ob_end_flush
,var_dump
,print_r
readfile
,passthru
,flush
,imagepng
,imagejpeg
among others and user-defined functions.Raw HTML areas
Unparsed HTML sections in a
. file are direct output as well.Script conditions that will trigger a
header()
call must be notedbefore any raw<html>
blocks.<!DOCTYPE html> <?
Use a templating scheme to separate processing from output logic.
- Place form processing code atop scripts.
- Use temporary string variables to defer messages.
- The actual output logic and intermixed HTML output should follow last.
Whitespace before
<? for "script.line 1" warnings
If the warning refers to output inline
1
, then it's mostlyleading whitespace, text or HTML before the opening<? token.
<?
Similarly it can occur for appended scripts or script sections:
?> <?
single linebreak after close tags. But it won'tcompensate multiple newlines or tabs or spaces shifted into such gaps.
UTF-8 BOM
Linebreaks and spaces alone can be a problem. But there are also "invisible"character sequences that can cause this. Most famously theUTF-8 BOM (Byte-Order-Mark)which isn't displayed by most text editors. It's the byte sequence
EF BB BF
, which is optional and redundant for UTF-8 encoded documents.  in the output (if the client interprets the document as Latin-1) or similar "garbage".In particular graphical editors and Java-based IDEs are oblivious to itspresence. They don't visualize it (obliged by the Unicode standard).Most programmer and console editors however do:
There it's easy to recognize the problem early on. Other editors may identifyits presence in a file/settings menu (Notepad++ on Windows can identify andremedy the problem),Another option to inspect the BOMs presence is resorting to an hexeditor.On *nix systems
hexdump
is usually available,if not a graphical variant which simplifies auditing these and other issues:An easy fix is to set the text editor to save files as "UTF-8 (no BOM)"or similar to such nomenclature. Often newcomers otherwise resort to creating new files and just copy&pasting the previous code back in.
Correction utilities
There are also automated tools to examine and rewrite text files(
sed
/awk
orrecode
).Fortag tidier.It rewrites close and open tags into long and short forms, but also easilyfixes leading and trailing whitespace, Unicode and UTF-x BOM issues:
It's safe to use on a whole include or project directory.
Whitespace after
?>
If the error source is mentioned as behind thethen this is where some whitespace or the raw text got written out.The
It's commonly advised, in particular to newcomers, that trailing
?>
eschews a small portion of these cases.(Quite commonlyinclude()d
scripts are the culprit.)Error source mentioned as "Unknown on line 0"
It's typically a
- It's occasionally the
gzip
stream encoding setting. - But it could also be any doubly loaded
extension=
modulegenerating an implicit
- It's occasionally the
Preceding error messages
If another
In this case you need to eschew the error,delay the statement execution, or suppress the message with e.g. or -when either doesn't obstruct debugging later on.
No error message
If you have error_reporting
or display_errors
disabled per ,then no warning will show up. But ignoring errors won't make the problem goaway. Headers still can't be sent after premature output.
So when header("Location: ...")
redirects silently fail it's veryadvisable to probe for warnings. Reenable them with two simple commandsatop the invocation script:
error_reporting(E_ALL);
ini_set("display_errors", 1);
Or set_error_handler("var_dump");
if all else fails.
Speaking of redirect headers, you should often use an idiom likethis for final code paths:
exit(header("Location: /finished.html"));
Preferably even a utility function, which prints a user messagein case of header()
failures.
Output buffering as a workaround
output bufferingis a workaround to alleviate this issue. It often works reliably, but shouldn'tsubstitute for proper application structuring and separating output from controllogic. Its actual purpose is minimizing chunked transfers to the webserver.
The setting nevertheless can help.Configure it in the or even onmodern FPM/FastCGI setups.
Enabling it will allowIt can likewise be engaged with a call to ob_start();atop the invocation script. Which however is less reliable for multiple reasons:
Even if
<? starts the first script, whitespace or aBOM might get shuffled before, .
It can conceal whitespace for HTML output. But as soon as the application logic attempts to send binary content (a generated image for example),the buffered extraneous output becomes a problem. (Necessitating
ob_clean()
as a further workaround.)The buffer is limited in size, and can easily overrun when left to defaults.And that's not a rare occurrence either, when it happens.
Both approaches therefore may become unreliable - in particular when switching betweendevelopment setups and/or production servers. This is why output buffering iswidely considered just a crutch / strictly a workaround.
See also the in the manual, and for more pros and cons:
- What is output buffering?
- Is using output buffering considered a bad practice?
- Use case for output buffering as the correct solution to "headers already sent"
But it worked on the other server!?
If you didn't get the headers warning before, then the to probe ifit's still possible to... send headers. Which is useful to conditionally printinfo or apply other fallback logic.
if (headers_sent()) {
die("Redirect failed. Please click on this link: <a href=...>");
}
else{
exit(header("Location: /user.
Useful fallback workarounds are:
HTML
<meta>
tagIf your application is structurally hard to fix, then an easy (butsomewhat unprofessional) way to allow redirects is injecting a HTML
<meta>
tag. A redirect can be achieved with:<meta http-equiv="Location" content="http://example.com/">
Or with a short delay:
<meta http-equiv="Refresh" content="2; url=../target.html">
This leads to non-valid HTML when utilized past the
<head>
section.Most browsers still accept it.JavaScript redirect
As alternative a JavaScript redirectcan be used for page redirects:
<script> location.replace("target.html"); </script>
While this is often more HTML compliant than the
<meta>
workaround,it incurs a reliance on JavaScript-capable clients.
Both approaches however make acceptable fallbacks when genuine HTTP header()calls fail. Ideally you'd always combine this with a user-friendly message andclickable link as last resort. (Which for instance is what the PECL extension does.)
Why setcookie()
and session_start()
are also affected
Both setcookie()
and session_start()
need to send a Set-Cookie:
HTTP header.The same conditions therefore apply, and similar error messages will be generatedfor premature output situations.
(Of course, they're furthermore affected by disabled cookies in the browseror even proxy issues. The session functionality obviously also depends on freedisk space and other
Further links
- Google provides a .
- And of course have been covered on Stack Overflow as well.
- The WordPress FAQ explains How do I solve the Headers already sent warning problem? in a generic manner.
- Adobe Community:
- Nucleus FAQ: What does "page headers already sent" mean?
- One of the more thorough explanations is HTTP Headers and the (Internet Archive link).It covers HTTP in detail and gives a few guidelines for rewriting scripts.
这篇关于如何修复“标题已发送"