所以我知道一般的经验法则是在PHP中进行头重定向之后,你应该调用exit()来避免运行额外的代码,但是我想知道你是否在重定向头之后放了代码,如果它会始终运行?
我正在研究各种跟踪Google Analytics中推介的方法,并发现了这篇文章:Google Analytics Tips & Tricks – Tracking 301 Redirects in Google Analytics
建议做这样的事情:
<?
Header( “HTTP/1.1 301 Moved Permanently” );
Header( “Location: http://www.new-url.com” );
?>
<script type=”text/javascript”>
var gaJsHost = ((“https:” == document.location.protocol) ? “https://ssl.” : “http://www.”);
document.write(unescape(“%3Cscript src=’” + gaJsHost + “google-analytics.com/ga.js’ type=’text/javascript’%3E%3C/script%3E”));
</script>
<script type=”text/javascript”>
try {
var pageTracker = _gat._getTracker(“UA-YOURPROFILE-ID”);
pageTracker._trackPageview();
} catch(err) {}</script>
从我总是理解header()函数的方式来看,它取决于浏览器,它可以随时运行重定向。因此,无法保证JavaScript在重定向发生之前实际开始或完成执行。
PHP's documentation for the header() function表示重定向后退出的原因是“确保我们重定向时下面的代码没有执行。”这听起来并不像他们保证所有后续代码都会运行,只是它可能会发生。
无论如何,我找到了一种实际管理跟踪的不同方法,但我想看看能否找到header()在这种情况下是如何工作的。
感谢您的帮助。
答案 0 :(得分:3)
这是竞争条件。将重定向标头发送到浏览器后,浏览器将关闭当前连接并为重定向URL打开一个新连接。在原始连接关闭并且Apache关闭脚本之前,您的代码将继续像以前一样执行。
理论上,如果客户端/服务器之间的连接足够快,并且管道中的任何地方都没有缓冲,则发出标头会导致脚本立即终止。实际上,它可以在“现在”和“从不”之间的任何地方启动关闭。
答案 1 :(得分:3)
在PHP中使用头函数只会添加到服务器返回的响应的标头中。它不会立即发送任何数据,也不会立即终止连接。 <{1}}调用后的任何代码都将执行。
特别是,即使在执行301重定向之后添加响应主体也是一个好主意,这样不支持重定向的客户端也会得到一些描述性响应。事实根据HTTP 1.1 specification 第10.3.2节 -
除非请求方法是HEAD,否则响应的实体应该是 包含一个简短的超文本注释,其中包含指向新URI的超链接。如果 响应除了以外的请求,接收301状态代码 GET或HEAD,用户代理不得自动重定向 除非可以由用户确认,否则请求,因为这可能 改变发出请求的条件。
答案 2 :(得分:0)
您的位置行之后的HTML不在PHP中运行;它会在浏览器中运行。浏览器是否执行您在该页面上包含的Javascript; PHP与它无关。
对我来说,PHP文档暗示发送重定向时header()
以下的任何PHP都会继续运行。但它在PHP解释器中“运行”,将JS转储到浏览器。它在PHP文档中的内容与JS是否由浏览器运行之间没有关系。
答案 3 :(得分:0)
修改强>:
好吧,正如Anupam Jain指出的那样,看起来浏览器不会在没有获得响应主体的情况下终止连接,这听起来很明智。所以我重新考虑了我的答案
这听起来并不像他们保证以下所有代码都会运行
完全如果有一些不应该执行的合理代码,则更有可能发出警告。例如,私人页面内容。因此,除了发送标头之外,您还必须确保没有发送敏感内容,退出看起来非常强大的解决方案。因此,我将其称为“确保下面的明智的代码在重定向时不会被执行。”
因此,无法保证JavaScript在重定向发生之前实际开始或完成执行。
完全它似乎与脚本执行无关,而是与浏览器在获得3xx响应后执行任何操作。我想我会测试它,但你也可以测试它。
答案 4 :(得分:0)
我注意到代码仍然执行,基于if语句的多个头文件可能导致“重定向循环错误”。我习惯于在每个标题重定向后添加die("Redirecting...");
,并且看不到问题仍然存在。