首页 > 解决方案 > 如何使用“标头已发送”常见错误(gCaptcha + 重定向)在 php 中重定向

问题描述

运行我的脚本时,我在调用 header() 时遇到这样的错误。我知道已经有答案(如何修复 PHP 中的“标头已发送”错误)但我不明白,在尝试了所有解决方案之后,只有 java 解决方案有效,这是一个非常糟糕的解决方案。如果没有 gCaptcha 部分(只有表单),我的代码正在工作,没有表单(只有 gCaptcha)我的代码也可以工作,但是如果组合代码不起作用......

对于每个 header() 调用,我的错误都是这样的:
“警告:无法修改标头信息 - 标头已由 C:\wamp64 中的(输出开始于 C:\wamp64\www\Travail\WebApp1\login.php:126)发送\www\Travail\WebApp1\login.php 在第 251 行"

我需要改变什么?老实说,我已经阅读了有关此问题的所有问题,但 8 小时后,我仍然无法通过真正的解决方案解决问题。

我的整个代码:

<?php 
    ini_set('display_errors', 1);
    ini_set('display_startup_errors', 1);
    error_reporting(E_ALL);
    session_start();
    require_once "config.php";
?>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <!-- Bootstrap CSS -->
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-+0n0xVW2eSR5OomGNYDnhzAbDsOXxcvSN1TPprVMTNDbiYZCxYbOOl7+AMvyTG2x" crossorigin="anonymous">
    <title>Login</title>
    
</head>
<body>

        <nav class="navbar navbar-dark bg-primary">
            <div class="container-fluid">
                <a class="navbar-brand" href="index.php">My Web App</a>
                <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
                <span class="navbar-toggler-icon"></span>
                </button>
                <div class="collapse navbar-collapse" id="navbarNav">
                <ul class="navbar-nav">
                    <li class="nav-item">
                    <a class="nav-link active" aria-current="page" href="#">Home</a>
                    </li>
                    <li class="nav-item">
                    <a class="nav-link" href="signup.php">Sign Up</a>
                    </li>
                    <li class="nav-item">
                    <a class="nav-link" href="login.php">Login</a>
                    </li>
                    <li class="nav-item">
                    <a class="nav-link disabled" href="#" tabindex="-1" aria-disabled="true">Admin</a>
                    </li>
                </ul>
                </div>
            </div>
        </nav>



    <div class="login-form">
        <?php 
            if(isset($_GET['login_err']))
            {
                $err = htmlspecialchars($_GET['login_err']);
                
                switch($err)
                {
                    case 'password':
                    ?>
                        <div class="alert alert-danger">
                            <strong>Error</strong> wrong password
                        </div>
                    <?php
                    break;

                    case 'email':
                    ?>
                        <div class="alert alert-danger">
                            <strong>Error</strong> invalid email
                        </div>
                    <?php
                    break;

                    case 'already':
                    ?>
                        <div class="alert alert-danger">
                            <strong>Error</strong>Please enter valide information
                        </div>
                    <?php 

                }
            }
            ?>
        <form method="post" id="demo-form">
                    <h2 class="text-center">Login</h2>
                    <input type="hidden" id="g-token" name="g-token" />       
                    <div class="form-group">
                        <input type="email" name="email" class="form-control" placeholder="Email" required="required" autocomplete="on">
                    </div>
                    <div class="form-group">
                        <input type="password" name="password" class="form-control" placeholder="password" required="required" autocomplete="off">
                    </div>
                    <div class="form-group">
                        <button type="submit" name="btnSubmit" class=" btn btn-primary btn-block" style=" margin-left: 35% ;"  >Login</button>
                    </div>
                    <div class="form-group">
                        <a href="forgot.php" style="margin-left:25%;"> Forgot password ? </a>
                    </div>
        </form>
    </div>
    
    <style>
            .login-form {
                width: 340px;
                margin: 50px auto;
            }
            .login-form form {
                margin-bottom: 15px;
                background: #f7f7f7;
                box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.3);
                padding: 30px;
            }

            .form-group {
                margin-top: 1em;;
            }


            .login-form h2 {
                margin: 0 0 15px;
            }
            .form-control, .btn {
                min-height: 38px;
                border-radius: 2px;
            }
            .btn {        
                font-size: 15px;
                font-weight: bold;
            }
    </style>

    <!-- Google Captcha Scripts -->
    <script src="https://www.google.com/recaptcha/api.js?render=6LcOd1cbAAAAAOiqthb4pwaH0vfrVDyB89D6q4V8"></script>
    
    <script>
        grecaptcha.ready(function() {
            grecaptcha.execute('6LcOd1cbAAAAAOiqthb4pwaH0vfrVDyB89D6q4V8', {action: 'homepage'}).then(function(token) {
                console.log(token);
            document.getElementById("g-token").value = token;
            });
        });
    </script>

    <!-- Optional JavaScript -->
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/js/bootstrap.bundle.min.js" integrity="sha384-gtEjrD/SeCtmISkJkNUaaKMoLD0//ElJ19smozuHV6z3Iehds+3Ulb9Bn9Plx0x4" crossorigin="anonymous"></script>

</body>
</html>


<?php 

        if(!empty($_POST["g-token"]) && !empty($_POST['email']) && !empty($_POST['password']))
        {

            

            $secretKey  = '6LcOd1cbAAAAALaDm52utDpT2bt6DNtMNNivW-9s';
            $token      = $_POST["g-token"];
            $ip         = $_SERVER['REMOTE_ADDR'];
        
            /* ======================= POST METHOD =====================*/ 
            $url = "https://www.google.com/recaptcha/api/siteverify?";
            $data = array('secret' => $secretKey, 'response' => $token, 'remoteip'=> $ip);
        
            // use key 'http' even if you send the request to https://...
            $options = array('http' => array(
                'method'  => 'POST',
                'content' => http_build_query($data),
                'header' => 'Content-Type: application/x-www-form-urlencoded'
            ));
            $context  = stream_context_create($options);
            $result = file_get_contents($url, false, $context);
            $response = json_decode($result);
            if($response->success)
            {
                echo '<center><h1>Validation Success!</h1></center>';
            }
            else
            {
                echo '<center><h1>Captcha Validation Failed..!</h1></center>';
            }

            //Avoid XSS
            $email = htmlspecialchars($_POST['email']);
            $password = htmlspecialchars(($_POST['password']));

            $email = strtolower($email);

            echo $email;
            echo $password;

            $check = $bdd->prepare('SELECT * FROM users WHERE email = ?');
            $check->execute(array($email));
            $data = $check->fetch();
            $row = $check->rowCount();

            echo $row;
            if($row > 0)
            {
                
                if(filter_var($email, FILTER_VALIDATE_EMAIL))
                {

                    if(password_verify($password, $data['password']))
                    {
                        $_SESSION['user'] = $data['token'];
                        //echo "<script type='text/javascript'>window.top.location='app.php';</script>"; exit;
                        header('Location: index.php');
                        die();
                    }else{echo "<script type='text/javascript'>window.top.location='login.php?login_err=password';</script>"; exit;
                        //header('Location: login.php?login_err=password'); die(); 
                    }
                }else{echo "<script type='text/javascript'>window.top.location='login.php?login_err=email';</script>"; exit; }
            }else{ echo "<script type='text/javascript'>window.top.location='login.php?login_err=already';</script>"; exit; }
            

        }
        else{  die();}

?>

如果我替换“header('Location: index.php');” BY“回声”window.top.location='app.php';“;退出;” 它有效,但它不是一个真正的解决方案。

顺便说一句,为了显示错误,我的前 3 行代码是否正确?(我正在使用 localhost wamp 运行代码)

标签: javascriptphphtml

解决方案


在将任何其他输出发送到页面之前,必须调用 header() 函数。因此,在您的情况下,您可能希望在输出 HTML 之前将页面底部的 PHP 代码表单处理块移动到顶部。请注意,这意味着您还需要将这些验证响应字符串分配给变量,并在适当的情况下在页面中进一步回显它们。


推荐阅读