【问题标题】:PHP header wont redirect with AJAXPHP 标头不会使用 AJAX 重定向
【发布时间】:2012-12-04 01:20:10
【问题描述】:

对于一个项目,我们必须创建一个基本的登录系统。我试图使用 REST 来管理我的整个页面。现在我相信我在这里遗漏或误解了一些关键概念,但多年来我一直试图弄清楚如何做到这一点。不允许在这个练习中使用库,所以我不能使用 JQuery。

所以这是我的问题:我有一个 .js 文件,用于检查用户名长度和密码长度等......在这个 .js 文件中,我还有一个 ajax 函数,可以将用户名和电子邮件发送到 PHP 以验证尚不存在使用 SQL 使用该电子邮件或用户名的现有用户。

function checkUser()
        {
            var ajax = new Ajax(); // instantiates my external ajax class
            var email = document.getElementById("newEmail").value;
            var username = document.getElementById("newUserName").value
            ajax.post("index.php?method=register&check=check", "newEmail=" + email + "&newUserName=" + username, callbackCatch)

        }
    function callbackCatch(param)   
        {
            var responseMessages = JSON.parse(param.responseText);

            emailMessage = responseMessages.emailMessage;
            userNameMessage = responseMessages.userNameMessage;
            userEmailIsOk = responseMessages.userEmailIsOk;
            userNameIsOk = responseMessages.userNameIsOk;
            release = true;
            if((userEmailIsOk + userNameIsOk) != 2)
                {
                    console.log(userEmailIsOk + userNameIsOk);
                    release = false;
                }

            updateMessageFields();
        }

我得到一个 JSON 字符串,我对其进行解析,然后与我的表单值进行比较。当一切都找到并且花花公子时,我单击表单页面上的注册按钮,该按钮将所有字段发布回我的 php 文件。但是,似乎当我这样做时,每次都会以某种方式访问​​我的外部 ajax 类,并且出现错误:NS_NOINTERFACE:组件没有请求的接口。

我假设因为每当我发帖时 AJAX 都会在后台运行,即使从我的表单中它也会尝试发回我的参数,在这种情况下是不兼容的。

我不知道如何解决这个问题。我应该处理传输的 PHP 文件如下所示:

require_once("../database/table.php");

类测试{

private $SQLtable;

private $newEmail;
private $newPswrd;
private $newUserName;
private $newFullName;


public function test()
    {
        $this->SQLtable = new table();
        $this->initClassVars();
        $this->generateUserName();
        $this->regUser();


    }
function initClassVars()
    {
        if(isset($_POST["newPassword"]))
            {
                $this->newPswrd = $_POST["newPassword"];
            }
        if(isset($_POST['newUserName']))
            {
                $this->newUserName = $_POST['newUserName'];
            }
        if(isset($_POST["newEmail"]))
            {
                $this->newEmail = $_POST["newEmail"];
            }
        if(isset($_POST["newFullName"]))
            {
                $this->newFullName = $_POST["newFullName"];
            }
    }
function generateUserName()
    {
        if(isset($_POST["newFullName"]))
        {
            $suggestedUserName = str_replace(" ", "", $this->newFullName);
            $this->newUserName = $suggestedUserName;
        }
    }

function regUser()
    {       

                $this->SQLtable->registerUser($this->newEmail, $this->newPswrd, $this->newFullName, $this->newUserName);
                $sessionKey = $this->genKey();
                $this->SQLtable->authUser($this->newEmail, $this->newPswrd, $sessionKey);
                header("location:Location:index.php?method=feed&key=$sessionKey&user=$this->newEmail");
                exit;
    }

function genKey($length = 16)
    {
        $options = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; //Range
        $key = ""; //Empty holder for key
        for($i = 0; $i < $length; $i++)
            {
                $code = rand(0, strlen($options) - 1); 
                $key .= $options[$code];  // Loops through as long as the $length is set and adds a random string char from $options to build a new key.
            }
        return $key;
    }

}

如您所见,我正在玩弄使用 API 密钥来控制身份验证。我还没有让 cookie 使用它,但是在我弄清楚如何对这个注册事物进行排序之后,我就不会这样做了。

对不起,如果我不清楚。这是我关于 stackoverflow 的第一个问题,基本上直到大约 8 个月前我才写过一行代码,所以请耐心等待我的新代码:D。谢谢。。

好的,这里是 HTML 以及函数被调用的位置: 这是我的表单 html 文件。当我反复使用它们时,文档类型和标题是分开添加的。

<body>

<h1> Thanks! <!-- $user -->, you're almost there.  We just need a few more details      </h1>

<form id="registerUser" name="registerUser" action="index.php?method=test" method="post">
<p>
<label for="newFullName">Full Name: </label>
<input type="text" id="newFullName" name="newFullName" value="$newFullName" />
<span id="nameMessage"></span>
</p>
<p>
<label for="newUserName">User Name: </label>
<input type = "text" id="newUserName" name="NewUserName" value="$newUserName" />
<span id="nicknameMessage"><!-- $newUserNameMessage --></span>
</p>
<p>
<label for="newEmail">Email: </label>
<input type="text" id="newEmail" name="newEmail" value="$newEmail" />
<span id = "newEmailMessage"><!-- $newEmailMessage --></span>
</p>
<p>
<label for ="newPassword">Password: </label>
<input type="password" id="newPassword" name="newPassword" value="$newPswrd" />
<span id = "newPasswordMessage"></span>
</p>
<input type="submit" id="register" disabled="disabled" value="Register" onclick=""/>
</form>


<p><a href="../../../Index.html"> Click here to go back to the login site and login.   </a></p>

<script type="text/javascript" language="javascript" src="../../js/net/ajaxHandler.js">    </script>
<script type="text/javascript" language="javascript">var bootstrap = new ajaxHandler();     bootstrap.init(); </script>
</body>
</html>

整个 JS 文件是这样的。。它有点乱,但这是因为我一直在玩弄它:

var ajaxHandler = function()
{
    var self = this;
    var release = true;
    var nameField;
    var userField;
    var emailField;
    var passWordField
    var emailMessage;
    var userNameMessage;

    self.init = function()
        {
            addEventListeners();
            checkFormForErrors();
        }

    self.redirect = function ()
        {
        }
    function addEventListeners()
        {
            nameField       = document.getElementById("newFullName");
            userField       = document.getElementById("newUserName");
            emailField      = document.getElementById("newEmail");
            passWordField   = document.getElementById("newPassword");

            Event.addEventListener(nameField, 'click', checkFormForErrors);
            Event.addEventListener(userField, 'click', checkUser);
            Event.addEventListener(emailField, 'click', checkUser);
            Event.addEventListener(passWordField, 'click', checkFormForErrors);

            Event.addEventListener(nameField, 'keyup', checkFormForErrors);
            Event.addEventListener(userField, 'keyup', checkUser);
            Event.addEventListener(emailField, 'keyup', checkUser);
            Event.addEventListener(passWordField, 'keyup', checkFormForErrors);
        }

    function checkPassword()
        {
        var passWordIsOk;
        var patt        = /\s/;
        var whiteSpace  = patt.test(passWordField);
        var passwordLength = passWordField.value.length;
        if (passwordLength < 8 )
            {
                document.getElementById("newPasswordMessage").innerHTML = "Your passowrd must be at least 8 charachters long. ";
                passWordIsOk = false
                if (whiteSpace)
                    {
                        document.getElementById("newPasswordMessage").innerHTML += "Your Password cannot contain any spaces.";
                        passWordIsOk = false
                    }
            } 
        else
            {
                document.getElementById("newPasswordMessage").innerHTML = "Password looks good";
                passWordIsOk = true
            }
        return passWordIsOk;
        }

    function checkName()    
        {
            var userNameIsOk;
            var nameMessage = document.getElementById("nameMessage");
            if (!nameField.value)
                {
                    nameMessage.innerHTML = "You need to enter a name."
                    userNameIsOk = false;

                }
            else
                {
                    nameMessage.innerHTML = "Name looks great."
                    userNameIsOk = true;
                }
            return userNameIsOk;
        }

    function checkEmailSyntax()
        {
            var EmailIsOk = true
            var patt    = /^([\w!.%+\-])+@([\w\-])+(?:\.[\w\-]+)+$/ ;
            var format  = patt.test(emailField.value);
            if (!format)
                {
                    document.getElementById("newEmailMessage").innerHTML = "Your email does not appear to be in the right format."
                    EmailIsOk = false;
                }
            return EmailIsOk        
        }

    function checkFullNameSyntax()
        {
            var nameIsOk = true
            if (document.getElementById("newUserName").value == "")
                {
                    document.getElementById("nicknameMessage").innerHTML = "You must enter a username.  You can always change it later."
                    nameIsOk = false
                }
            return nameIsOk;
        }

    function checkUser()
        {
            var ajax = new Ajax();
            var email = document.getElementById("newEmail").value;
            var username = document.getElementById("newUserName").value
            ajax.post("index.php?method=register&check=check", "newEmail=" + email + "&newUserName=" + username, callbackCatch)

        }
    function callbackCatch(param)   
        {
            var responseMessages = JSON.parse(param.responseText);

            emailMessage = responseMessages.emailMessage;
            userNameMessage = responseMessages.userNameMessage;
            userEmailIsOk = responseMessages.userEmailIsOk;
            userNameIsOk = responseMessages.userNameIsOk;
            release = true;
            if((userEmailIsOk + userNameIsOk) != 2)
                {
                    console.log(userEmailIsOk + userNameIsOk);
                    release = false;
                }

            updateMessageFields();
            var ajax = "";
        }
    function updateMessageFields()
        {
            document.getElementById("nicknameMessage").innerHTML = userNameMessage;
            document.getElementById("newEmailMessage").innerHTML = emailMessage;
            checkFormForErrors();

        }
    function checkFormForErrors()
        {
            console.log('hi');
            var nameOk = checkFullNameSyntax()
            console.log(nameOk);
            var passOk = checkPassword()
            console.log(passOk);
            var userOk = checkName()
            console.log(userOk);    
            var emailOk = checkEmailSyntax()
            console.log(emailOk);
            console.log(release);
            document.getElementById("register").disabled = true;
            if(release && nameOk && passOk && userOk && emailOk)
                {
                    console.log('hey');
                    console.log(release && nameOk && passOk && userOk && emailOk)
                    document.getElementById("register").disabled = false;
                }
        }
}

【问题讨论】:

  • 所以你的主要问题是来自 PHP 的重定向?当你用 AJAX 调用它时会发生什么?
  • 是的,我相信。在 regUser() 下,我想用不同的方法再次将页面发送到 index.php。然后该方法用另一个 php 类实例化我的用户主页。
  • 更改它,如果成功,您的 AJAX 请求会返回要重定向到的 URL,然后在成功回调中使用 document.location.href = [url] 完成重定向
  • 我想我可以做到。我只是希望不必将一堆变量传递回我的javascript。我首先使用 javascript 的唯一原因是如果用户名密码...等都可以,则立即向用户显示。

标签: php javascript ajax rest header


【解决方案1】:

我不知道这是否难以理解,但是当您的 AJAX 收到响应时,页面已经被重定向......并且到您的 AJAX,它看起来很正常 - 它正在收到响应(在这种情况下,是整页,而不是 JSON)。这是事件的顺序:

AJAX Request

--> Browser sends request to PHP file

----> Your PHP file receives the request, processes it, and "redirects"

<---- HTTP 302 status code sent to browser

<-- Browser receives 302 status code, redirects response, and returns result as AJAX response

至少我很确定会发生这种情况 - 我发誓我以前遇到过这个“问题”,我发现这就是正在发生的事情。

要“解决”这个问题,您有几个选择。您可以在 JSON 中发送此信息,而不是使用 PHP 来“重定向”。然后,在您的回调中,您可以检查它的存在......就像一个“重定向”键,并使用它的值重定向到(在 PHP 中设置它的值作为重定向到的 URL)。或者,您可以将其保留为字符串,并在解析它之前,以“redirect:”开头检查它。如果它以此开头,则获取字符串的其余部分并重定向到该值(在 PHP 中将其值设置为要重定向到的 URL)。否则,像JSON一样解析并正常处理。

【讨论】:

  • 好吧,因为我有一个 ajax 实例正在运行,它会处理我的表单提交并返回状态和重定向,而不是允许 php 设置它?我想我无论如何都明白。遗憾的是,除了这个注册页面之外,我还有一个登录页面,我的表单和 POST 操作可以完美运行
  • @ChrisShields 嗯不是真的。 AJAX 没有“运行”。当您发出 AJAX 请求时,它与您的其余代码是异步的。它在网页的后台发出一个特殊的 HTTP 请求。您对其进行设置,以便它知道在收到响应(回调)时要运行什么代码。正常的 POST 提交工作正常,因为它是重定向的正常操作。因为在这种情况下它是一个 AJAX 请求,所以浏览器处理响应的方式略有不同,并且会弄乱您的预期。正如我们已经指出的那样,您只需为其编写一些不同的代码 - 可能在 JSON 中设置它
  • 是的,我认为这与此有关。不过,我仍然看不到我的表单是如何与我的 javascript 文件中编写的 ajax 代码相关联的。如果我有某种功能正在听我的表格,那么我会理解的。但我在我的 js 中拥有的唯一 ajax 代码是这里显示的那 2 个函数。只有当我单击字段时才会调用这些函数,我没有与表单本身或提交按钮绑定的事件侦听器。这让我很困惑
  • 你能显示这些函数的确切调用位置吗?和/或相关的 HTML?也许我们可以用这种方式解释发生了什么
  • 难以置信......有时当出现问题时,我显然需要深入了解原因,我错过了明显的简单问题......:p。如果我删除单击事件侦听器,它会起作用。唯一不清楚的部分是元素如何监听点击。除了输入“提交”元素之外,我在输入字段本身上都有我的所有点击侦听器。但显然,当我点击提交元素时,evnetlistener 会触发?为什么单击非侦听输入元素时我的事件侦听器会触发?
【解决方案2】:

您不能在 ajax 调用中从 php 重定向。

您需要将正确的信息从您的 php 脚本发送回您的 javascript,并使用您从 php 返回的参数从那里进行重定向。

您的 php 中还有一个 Location: 太多,但这不是问题所在。

【讨论】:

  • 当我点击 input="submit" 按钮时,这是一个 AJAX 调用吗?因为在我的登录页面中,当我单击提交时,POST 已正确发送到 PHP,并且重定向发生时没有问题。
  • @Chris Shields 您应该知道 :-) 如果没有看到您的 html 和 javascript,我不知道您是否正在捕获来自提交事件、按钮单击事件或 javascript 中的任何内容。
  • 是的,只是我认为除了我实例化的 ajax 之外,一个表单会执行自己的单独 AJAX 调用。我的表单如下所示:
  • 啊....太大了,无法复制到这里。它只是一个常规形式
  • 好吧.. 我从未使用过 jsfiddle.net。看起来好像它使用了不幸的是我们不应该在这个练习中使用的库
猜你喜欢
  • 2021-07-16
  • 2021-09-08
  • 2013-08-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多