简体   繁体   中英

PHP header redirect works on Apache, but not Nginx

I have a contact form that will resubmit data if you refresh the page, so I added header("Location: http://www.example.com/form.php"); at the end of it so the page redirects back to itself and ultimately resets the form, preventing it from being submitted multiple times. It works exactly how I want it to on my local Apache server, but when I use the same code on an Nginx server, the form stops working altogether. Removing header("Location: http://www.example.com/form.php"); allows the form to work on the Nginx server, but then I will still have the resubmitting issue.

Is there a way to get header redirects to work with Nginx? If not, is there an alternative way to prevent my form from being resubmitted when people refresh the page?

Note: I tried adding header("HTTP/1.0 301 Moved Permanently"); on the line above header("Location: http://www.example.com/form.php"); , as that was a possible solution I found, but it didn't solve anything.

EDIT: I put example.com in my post as I didn't want to put the real URL I am redirecting to.

Here is some code:

 <?php
        // define variables and set to empty values
        $firstnameErr = $lastnameErr = $emailErr = $companyErr = "";
        $firstname = $lastname = $email = $company = $comments = "";


        if ($_SERVER["REQUEST_METHOD"] == "POST") {
            $error = false;
            //Verifying first name input
            if (empty($_POST["firstname"])) {
                $firstnameErr = "First name is required";
                $error = true;
            } else {
                $firstname = test_input($_POST["firstname"]);
                // Check if first name only contains letters and whitespace
                if (!preg_match("/^[a-zA-Z ]*$/", $firstname)) {
                    $firstnameErr = "Only letters and white space allowed";
                    $error = true;
                }

            }

            //Verifying last name input
            if (empty($_POST["lastname"])) {
                $lastnameErr = "Last name is required";
                $error = true;
            } else {
                $lastname = test_input($_POST["lastname"]);
                // Check if last name only contains letters and whitespace
                if (!preg_match("/^[a-zA-Z ]*$/", $lastname)) {
                    $lastnameErr = "Only letters and white space allowed";
                    $error = true;
                }
            }

            //Verifying email input
            if (empty($_POST["email"])) {
                $emailErr = "Email is required";
                $error = true;
            } else {
                $email = test_input($_POST["email"]);
                // Check if email is well-formed
                if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
                    $emailErr = "Invalid email format";
                    $error = true;
                }
            }

            //Verifying company input
            if (empty($_POST["company"])) {
                $companyErr = "Company name is required";
                $error = true;
            } else {
                $company = test_input($_POST["company"]);
            }

            //Verifying comments input (empty input is allowed)
            if (empty($_POST["comments"])) {
                $comments = "";
            } else {
                $comments = test_input($_POST["comments"]);
            }

            if (!$error){
            // Email sent to me
            mail("example@example.com", "Email subject", "Email message");
            // Confirmation email to potential client
            mail("example@example.com", "Email subject", "Email message");
            }
            // Loads new, empty form (otherwise refreshing page will resubmit form)
            header("HTTP/1.0 301 Moved Permanently");
            header("Location: http://www.example.com/request.php");
        }


        function test_input($data) {
            $data = trim($data);
            $data = stripslashes($data);
            $data = htmlspecialchars($data);
            return $data;
        }
      ?>


 <form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>" method="post">
    <label>Name*</label>
    <input type="text" name="firstname" placeholder="First" size="20">
    <span class="error"><?php echo $firstnameErr;?></span>
    <input type="text" name="lastname" placeholder="Last" size="20" class="form-control">
    <span class="error"><?php echo $lastnameErr;?></span>
    <label>Email*</label>
    <input type="text" name="email" placeholder="Email" size="50" class="form-control">
    <span class="error"><?php echo $emailErr;?></span>
    <label>Company*</label>
    <input type="text" name="company" placeholder="Company" size="50" class="form-control">
    <span class="error"><?php echo $companyErr;?></span>
    <label>Comments</label>
    <textarea rows="4" name="comments" placeholder="Comments..." class="form-control"></textarea>
    <br>
    <input type="submit" value="Submit" class="submit-btn">
</form>
header('Status: 301 Moved Permanently', false, 301);    
header('Location: http://www.thedigideck.com/request.php');    
exit();      

Or just use this redirect function

function redirect($url) {
  $content = sprintf('<!DOCTYPE html>
  <html>
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="refresh" content="1;url=%1$s" />

    <title>Redirecting to %1$s</title>
  </head>
  <body>
    Redirecting to <a href="%1$s">%1$s</a>.
  </body>
  </html>', htmlspecialchars($url, ENT_QUOTES, 'UTF-8'));

  header('Location: ' . $url);

  die($content);
}

So it sets redirect header and returns body with redirect if the header didn't work.

The issue is probably related to the hosting server nginx is running on, not the fact that there is a difference in nginx and apache. The header function must be called at the beginning of the page, which works on localhost, but not when wrapped by a 3rd party host.

You could try using a meta tag for the redirect such as: echo "http://domain.com'>";

I had the same problem and I found that it was because a header("Status: 200 OK", false, 200); before the header to redirect. So I added a condition not to display the header 200 if I know that I will have to redirect:

    if(!isset($_GET['utm_source'])) { //Header will be Redirect 301 from global_cookies.inc.php
        header("Status: 200 OK", false, 200);
    }

Note : With Apache I had not this problem and could redirect even after a header 200.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM