0

我正在重构一些旧代码并试图headers更好地理解。

我在发送标头之前没有输出的以下帖子中阅读了一个很棒的答案! 现在我明白了“为什么”,但是在实现方面它仍然有点模糊。

当使用搜索的值单击取消按钮时,我的当前页面会重定向回来。

我存储发出请求的页面和会话变量中的值,允许我这样做:

if (isset($_SESSION['searchPage'])){
 header('Location:searchForm.php?ticket='.$_SESSION['product'].'&searchbtn=Search');
 exit();
}

但是,要在显示页面中进行这项工作,我必须使用ob_start().

为了避免这种解决方法,我发现我可以通过 javascript 重定向:

if (isset($_SESSION['searchPage'])){
    echo '<script>window.location="searchForm.php?product='.$_SESSION['product'].'&searchbtn=Search";</script>';    
    exit(); 
}

现在回答我的问题

  1. 哪种方法更好或可以接受?
  2. 我似乎想不出一种方法来设计我的页面,使其在使用之前不发送任何输出header()。如果按钮单击事件导致重定向,您如何在不使用的情况下处理 php 中的重定向ob_start()
4

5 回答 5

4

编辑
首先,您可能需要阅读更多关于使用header. 不只是设置header('Location:...');,而是使用以下代码重定向:

header ('HTTP/1.1 301 Moved Permanently');
header('Location:searchForm.php?ticket='.$_SESSION['product'].'&searchbtn=Search');

301 重定向通常更适合 SEO,并且大多数浏览器都会缓存重定向,因此客户端历史堆栈会更可靠,这对于可能使用历史记录的 JS 脚本来说是个好消息...

  1. 哪种方法更好?

php。仅仅依靠 JS 来重定向客户端并不是一个好主意。客户可能会关闭您的脚本,或者如果 JS 代码中出现一些错误,重定向将不起作用。一些无聊的青少年可能会想弄乱您的代码,并在您的站点中发现可能的安全问题。

   2. 怎么用ob_*header没有怎么用ob_*

只需通过调用启动您的输入脚本 ( index.php) ob_start(),以确保。也许使用ob_implicit_flush(true), 来隐式刷新输出缓冲区。但更重要的是,只需ob_flush()在设置标题后立即调用。
或者考虑使用像 Symfony2 和/或 ZendFW 这样的框架。处理重定向的代码已经为您编写了很多次,为什么不使用它呢?

如果您想避开输出缓冲,也许您可​​能需要考虑遵循某些模式或设计原则(如 MVC、IPO 等)并将您的代码写入 (+-)始终遵循此顺序来处理业务:

  • 获取请求
  • 处理请求中的数据,确定客户端要求的数据
  • 结构数据
  • 渲染页面
  • 发送响应

处理完请求后,您将能够立即重定向,并且由于您甚至还没有接近呈现输出,更不用说发送标头了,您可以安全地重定向和/或设置标头...

更新:
只是一个链接,以回应您的后续问题Gruyere 有一个关于 XSS 攻击的特殊部分,您可能想阅读......虽然我相信该文档的主要目的是如何安全地使用混搭(实际上是真正的 XSS 注射)。无论如何,他们在解释为什么以及如何使用 JS 来破坏任何 webapp 的安全性方面做得更好。

于 2013-06-21T11:57:11.970 回答
1

在服务器端做总是更好。从 SEO 的角度来看,如果用户禁用了 JavaScript,或者下载您的 JS 文件时出现问题,或者其中存在停止执行的错误,JavaScript 会重定向。

于 2013-06-21T12:07:21.370 回答
0

PHP重定向是最好的。因为即使用户在他的浏览器中禁用了脚本。

如果您使用的是 noscript 重定向,那么您可以使用 JS 而不是 PHP,这样在这种情况下您可以避免使用 ob_start()。

于 2013-06-21T11:57:56.817 回答
0

我建议采用以下方法:

function universal_redirect($url, $force_js = false) {
    if (headers_sent() || $force_js) {
        print('<script type="text/javascript">');
        printf("location.href='%s';", $url);
        print('</script>');
    } else {
        header('Location: ' . $url);
    }
}

它并不总是适用,但如果您构建管理页面或者当您的项目足够大且足够复杂以至于您不能总是保证输出尚未开始时,它是一个很好的解决方案。

一般来说,由于@Elias Van Ootegem 给出的原因,PHP 重定向要好得多。

于 2013-06-21T12:25:05.823 回答
0

如果您只想通过单击按钮将用户发送到另一个页面,为什么不只是实现一个链接:

<a href="searchForm.php?ticket=<?=$product?>&searchbtn=Search">go back</a>

或按钮:

<button onclick="window.location='searchForm.php?ticket=<?=$product?>&searchbtn=Search'">go back</button>
于 2013-06-21T12:07:14.103 回答