【问题标题】:PHP: header() function not redirecting. When redirecting with HTML or JavaScript, Session information is lostPHP:header() 函数未重定向。使用 HTML 或 JavaScript 重定向时,会话信息丢失
【发布时间】:2012-07-08 08:48:27
【问题描述】:

这是一个 PHP/Apache 问题...

  1. 我有以下代码。我要特别强调的是 以下:

          // store email in session variable
    
          $_SESSION["jobseeker_email"] = $_POST["jobseeker_email"];
    
          // perform redirect
    
          $target = util_siblingurl("jobseekermain.php", true);
    
          header("Location: " . $target);
    
          exit; /* ensure code below does not executed when we redirect */
    

这就是问题所在。当我在 localhost 上执行此代码时,它工作正常, 但是当我在远程服务器(这是一个 ipage.com 托管站点)上执行它时,我 得不到想要的结果。实际上,当 header("Location: $target); 部分运行时 我看到一个空白页面(并且没有重定向)。好像之前输出了什么东西 对 header() 的调用,但事实并非如此,因为我已经检查过了。那为什么不是 工作吗?

  1. 如果我注释掉调用 header() 的部分然后退出,我可以 执行 html 重定向或 javascript 重定向。但是,当我这样做时 我丢失了会话变量 $_SESSION["jobseeker_email"]。我不明白为什么 发生这种情况。

任何有关这些问题的帮助将不胜感激,因为我需要执行重定向 并且仍然保留前一页的会话状态,所有这些都在服务器上 (不只是在本地主机上)。

    <?php

      session_start();

      require_once('include/connect.php');
      require_once('include/util.php');

      util_ensure_secure();

      if (isset($_GET['logout'])) {

        session_destroy();

        // restart session

        header("Location: " . util_selfurl(true));

      }

      function do_match_passwords($password1, $password2) {

        return strcmp($password1, $password2) == 0;

      }

      function valid_employer_login($email, $password) {

        global $mysqli;

        global $employer_error;

        $query = "SELECT passwd FROM Employer WHERE email = '" . $mysqli->escape_string($email) . "'";

        $result = $mysqli->query($query);

        util_check_query_result($query, $result);

        $invalid_credentials = false;

        if ($result->num_rows == 0) {

          $invalid_credentials = true;

        } else {

          $row = $result->fetch_assoc();

          $retrieved_password = $row["passwd"];

          if (!do_match_passwords($password, $retrieved_password))

        $invalid_credentials = true;

        }

        if ($invalid_credentials) {

          $employer_error = "Invalid credentials.";

          return false;

        }

        return true;

      }

      function valid_jobseeker_login($email, $password) {

        global $mysqli;

        global $jobseeker_error;

        $query = "SELECT passwd FROM JobSeeker WHERE email = '" . $mysqli->escape_string($email) . "'";

        $result = $mysqli->query($query);

        util_check_query_result($query, $result);

        $invalid_credentials = false;

        if ($result->num_rows == 0) {

          $invalid_credentials = true;

        } else {

          $row = $result->fetch_assoc();

          $retrieved_password = $row["passwd"];

          if (!do_match_passwords($password, $retrieved_password))

        $invalid_credentials = true;

        }

        if ($invalid_credentials) {

          $jobseeker_error = "Invalid credentials.";

          return false;

        }

        return true;

      }

      if (isset($_POST["employer_submitted"])) {

        global $error;

        // check whether specified username and password have been entered correctly

        if (valid_employer_login($_POST["employer_email"], $_POST["employer_password"])) {

          // store email in session variable

          $_SESSION["employer_email"] = $_POST["employer_email"];

          // perform redirect

          $target = util_siblingurl("jobseekermain.php", true);

          header("Location: " . $target);

          exit; /* ensure code below does not executed when we redirect */

        }

      }

      if (isset($_POST["jobseeker_submitted"])) {

        global $error;

        // check whether specified username and password have been entered correctly

        if (valid_jobseeker_login($_POST["jobseeker_email"], $_POST["jobseeker_password"])) {

          // store email in session variable

          $_SESSION["jobseeker_email"] = $_POST["jobseeker_email"];

          // perform redirect

          $target = util_siblingurl("jobseekermain.php", true);

          header("Location: " . $target);

          exit; /* ensure code below does not executed when we redirect */

        }

      }

    ?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
      <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title>Work Net: Sign In</title>
        <link href="css/style.css" rel="stylesheet" type="text/css" />
      </head>
      <body>
        <div id="container">
          <h1>Work Net: Sign In</h1>
          <div id="content">
        <ul>
          <li>
            <h2>Employers</h2>
            <p><a href="accountcreate.php?accounttype=employer">Create new employer account.</a></p>
            <form method="post" action="<?php util_selfurl(true); ?>">
              <table>
            <tr>
              <td>E-mail:</td>
              <td><input type="text" name="employer_email" value="<?= htmlentities(util_setvalueorblank($_POST['employer_email'])); ?>" />
            </tr>
            <tr>
              <td>Password:</td>
              <td><input type="password" name="employer_password" value="<?= htmlentities(util_setvalueorblank($_POST['employer_password'])); ?>" /></td>
            </tr>
              </table>
              <?php if (isset($employer_error)) echo "<p style=\"color: red;\">" . htmlentities($employer_error) . "</p>"; ?>
              <input type="hidden" name="employer_submitted" />
              <input type="submit" value="Sign In" />
            </form>
            <p><a href="forgottenpassword.php?accounttype=employer">Forgotten Employer Password.</a></p>
          </li>
          <li>
            <h2>Job Seekers</h2>
            <p><a href="accountcreate.php?accounttype=jobseeker">Create new job seeker account.</a></p>
            <form method="post" action="<?php util_selfurl(true); ?>">
              <table>
            <tr>
              <td>E-mail:</td>
              <td><input type="text" name="jobseeker_email" value="<?= htmlentities(util_setvalueorblank($_POST['jobseeker_email'])); ?>" />
            </tr>
            <tr>
              <td>Password:</td>
              <td><input type="password" name="jobseeker_password" value="<?= htmlentities(util_setvalueorblank($_POST['jobseeker_password'])); ?>" /></td>
            </tr>
              </table>
              <?php if (isset($jobseeker_error)) echo "<p style=\"color: red;\">" . htmlentities($jobseeker_error) . "</p>"; ?>
              <input type="hidden" name="jobseeker_submitted" />
              <input type="submit" value="Sign In" />
            </form>
            <p><a href="forgottenpassword.php?accounttype=jobseeker">Forgotten Job Seeker Password.</a></p>
          </li>
        </ul>
          </div>
          <div id="footer">
        <p>
          <?php include('markup/footer.php'); ?>
        </p>
          </div><!-- end #footer -->
        </div><!-- end #container -->
      </body>
    </html>

【问题讨论】:

  • 听起来像是 UTF8-BOM 问题。你怎么确定header之前没有输出,你收到什么headers?
  • 当你看到一个空白页面并且没有重定向服务器的响应内容是什么?
  • 你能显示 var_dump(util_siblingurl("jobseekermain.php", true) );的输出吗
  • var_dump 的输出是:string(59) "timescapezonecom.ipage.com/worknet/jobseekermain.php" (这与我在名为timescapezonecom.ipage.com/worknet/login.php 的文件中发布的代码不同)。
  • @JohnGoche 你启用错误报告了吗?

标签: php javascript apache redirect http-redirect


【解决方案1】:

如果没有看到 util_siblingurl() 的代码,我的猜测是你的问题是一个路径问题。您的 util_siblingurl() 函数和 Apache 设置的组合可能会导致路径不一致。

例如,在本地主机上,您可能会被重定向到http://example.com/some/path/to/jobseekermain.php,而在远程主机上,您可能会被重定向到http://example.com/some/different/path/to/jobseekermain.php

您看到的是白屏而不是 404,这让我对这个假设有些犹豫,但查看该函数的代码仍然会有所帮助。

【讨论】:

  • OP看到白屏的事实是因为他可能没有启用错误报告(就像他应该的那样)。
  • 好的,我已经添加了 ini_set('display_errors', 1);并得到以下信息: 0 Internal Server Error 服务器遇到内部错误或配置错误,无法完成您的请求。请联系服务器管理员 cgiadmin@yourhostingaccount.com 并告知他们错误发生的时间,以及您可能所做的任何可能导致错误的事情。服务器错误日志中可能会提供有关此错误的更多信息。
  • 网络服务器是 ipage.com,大概是网络上最臭名昭著的网络托管服务。它怎么能输出这个?不是代码问题的服务器问题?这是怎么回事?我已经联系了那里的工作人员,但他们告诉我“这是编码问题,请联系网站管理员”。嗯,有人知道具体的问题是什么吗?
  • 这看起来像是一个 500 错误,可能是由在发送任何输出之前发生的致命 PHP 错误引起的。您可以访问 Apache 错误日志吗?
  • 实际上,在调用 header() 之前包括几乎任何文件都会导致错误,真是太糟糕了,就好像文件末尾有一些空间导致问题一样。它甚至可能在上传到服务器后被添加,因为在本地机器上我看不到问题。
【解决方案2】:

我可能会做两件事来找出问题所在:

  1. 使用 Wireshark。准确查看您收到的标题。这可能会告诉您问题的确切原因(也许主机总是在页面顶部打印一些东西,就像一些免费主机一样?)
  2. 检查其他标头重定向是否有效。创建一个简单地执行重定向的 php 脚本,其中包含硬编码的值,并查看它是否有效。如果是这样,则意味着您的代码中的某些内容会打印到页面上,或者您由于某种原因没有成功构建目标 URL。

这是一个示例脚本:

<?php
    session_start();

    // I added the require just to make sure nothing is being printed there
    // (an error for example)
    require_once('include/connect.php');
    require_once('include/util.php');

    header("Location: " . SOME_LOCATION);
    exit;
?>

当然还有一些网页,当你重定向到它时可以打印出来......

【讨论】:

  • 你好,我用过wireshark。 HTTP 部分只有一个标准的 GET /worknet/login.php HTTP/1.1,然后是一个 HTTP/1.1 200 OK。但是,当我尝试您发布的脚本时,我也得到了白色的空白页面并且没有重定向,这当然意味着这两个文件的包含导致了问题?
  • 很容易测试 require 是否导致问题:只需删除 require 指令并再次尝试脚本。如果它有效,那么问题出在 require 上。
  • 当我删除它时,我仍然在文档类型之前得到零字符。
  • 我从您的评论中不明白,如果您删除了要求说明,是否正在执行重定向..
【解决方案3】:

我相信您的代码没有问题。实际上,像托管系统这样的 ipage 会导致一些问题。我也使用过 ipage 托管计划并面临同样的问题。

所以,伙计,尝试寻找另一个比这些更好的托管服务器。

谢谢

【讨论】:

    【解决方案4】:

    我遇到了同样的问题。 Ipage 托管、重定向不起作用,服务器报告标头已发送。原来是空格的问题。

    确保&lt;?php code ?&gt; 标签之外没有空格或任何其他字符。在重定向之前包含的所有文件中,手动选择并删除开始标记之前和结束标记之后的所有内容。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-31
      相关资源
      最近更新 更多