0

我正在尝试使用 AJAX 来改进我的登录系统以在不刷新页面的情况下运行。我对ajax很陌生。我发现的教程都使用 GET。我不想使用get。这是我的代码:

login.php(我从中删除了 CSS 代码)

<html>
<script type="text/javascript" src = "login/loginJS.js"></script>
    <body>
    <center>
        <div class="rounded">
        <form method='POST' action = "processLogin.php">
            Username:<input type="text" class = "input1" name = "username"/><br>
            Password:<input type="password" class = "input1" name = "password"/><br>
            Remember Me?<input type="checkbox" name = "remember"/?><br>
            <?php
            session_start();
            echo'<p id="errorField" class="error"></p>';
            ?>
            <input type="submit" value = "Login" class = "button" onclick='process()'/>
            <b><p>New User? <a href="register.php">Register</a></p></b>
        </form>
        </div>
    </center>
    </body>
</html>

loginJS.js

xmlHttp = createXmlHttpRequestObject();

function createXmlHttpRequestObject()
{
    var xmlHttp;

    if (window.ActiveXObject){
        try{
        xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
        }catch(e){
        xmlHttp = false;
        }
    }else{
        try{
            xmlHttp = new XMLHttpRequest();
        }catch(e){
            xmlHttp = false;
        }
    }

    if(!xmlHttp){
        alert("The XML Http Request Failed");
    }else{
        return xmlHttp;
    }
}

function process(){
    if (xmlHttp.readyState == 4 || xmlHttp.readyState == 0){
        login = encodeURIComponent(document.getElementById("loginField").value);
        xmlHttp.open("POST", "login/processLogin.php",true);
        xmlHttp.onreadystatechange = handleServerResponse;
        xmlHttp.send();
    }else{
        setTimeout('process()',1000);
    }
}

function handleServerResponse(){
    if(xmlHttp.readyState == 4){
        if(xmlHttp.status == 200){
            xmlResponse = xmlHttp.responseXML;
            xmlDocumentElement = xmlResponse.documentElement;
            message = xmlDocumentElement.firstChild.data;
            document.getElementById("errorField").innerHTML = message;
        }
    }
}

进程登录.php

      <?php
    session_start();
    header('Content-Type: text/xml');
    echo '<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>';
    echo "<response>";
        $username = $_POST['username'];
        $password = $_POST['password'];
        if ($username == '' or $password == '')
        {
            echo 'The username/password fields may not be blank.';
        }else{
            echo 'This is a test';
        }
    echo "</response>";
?>

所以我的问题是,我应该怎么做才能把输入文本和密码字段中的变量作为一个 post 变量,然后用 javascript 发送它。我只需要发送用户名和密码字段。要查看网站, http: //rukiryo.bugs3.com 网站是这样的。当我使用我的页面刷新方法时,登录按钮有效,但我无法弄清楚使其适用于非刷新的最后步骤。

谢谢,亚历克斯

4

4 回答 4

3

那么在上面的代码中,您似乎没有使用 AJAX 请求发送登录参数。此外,您忘记显式设置为 Content-type 标头,这在执行 POST 请求时是必需的。

    xmlHttp.open("POST", "login/processLogin.php",true);
    xmlHttp.onreadystatechange = handleServerResponse;
    xmlHttp.send();  // <--This is your problem

您发布没有参数的空白发送

这是添加参数的方法

xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");  
xmlhttp.send("username=carl&password=XYZ");

显然,您必须对这些参数进行 url 编码,因此请使用它(这样 +、* 等内容就不会出现在 URL 中并毁了您的生活)

var params= "username="+encodeURIComponent("carl")+"&password="+encodeURIComponent("XYZ");
xmlhttp.send(params);

哦,在 PHP 端,你应该运行urldecode来取回你的字符串

于 2013-04-19T02:33:41.737 回答
1

好的,这是冗长的,简单的 ol' vanilla JavaScript 方法。我将假设您需要对 < IE6 的支持,因此首先要做的是检查浏览器支持哪个 xhr 对象。

function createXHR() {
    if (typeof XMLHttpRequest !== "undefined") {
        return new XMLHttpRequest();
    } else {
        var versions = ["MSXML2.XmlHttp.6.0", "MSXML2.XmlHttp.3.0"];

        for (var i = 0, len = versions.length; i < len; i++) {
            try {
                var xhr = new ActiveXObject(versions[i]);
                return xhr;
            } catch (e) {
                // do nothing
            }
        }
    }
    return null;
}

接下来是将 onsubmit 事件处理程序附加到表单。这就是 jQuery 在处理非 DOM 兼容浏览器方面的优势所在。尽量不要冗长,这里有一个简短的方法来说明这一点。

var form = document.form[0];

function addEventListener(el, evt, fn) {
    if (typeof addEventListener === "function") {
        el.addEventListener(evt, fn, false);
    } else {
        e.attachEvent("on" + evt, fn);
    }
}

然后添加 onclick 事件处理程序并传入您要在提交时调用的函数:

addEventListener(form, 'click', process);

在深入研究流程函数之前,我将创建一个序列化表单字段的函数。这是我使用的一个:

function serialize(form) {
var parts = [],
    field = null,
    i,
    len,
    j,
    optLen,
    option,
    optValue;

for (i = 0, len = form.elements.length; i < len, i++) {
    field = form.elements[i];

    switch(field.type) {
        case "select-one":
        case "select-multiple":

            if (field.name.length) {
                for ( j = 0, optLen = field.options.length; j < optLen; j++) {
                    option = field.options[j];
                    if (option.selected) {
                        optValue = "";
                        if (option.hasAttribute) { //DOM compliant browsers
                            optValue = (option.hasAttribute("value") ? 
                                option.value : option.text);
                        } else {
                            optValue = (option.attributes["value"].specified ? 
                                option.value : option.text);
                        }
                        parts.push(encodeURIComponent(field.name) + "=" + encodeURIComponent(optValue));
                    }
                }
            }
            break;

        case undefined: //fieldset 
        case "file":    //file input
        case "submit":  //submit button
        case "reset":   //reset button
        case "button":  //custon button
            break;

        case "radio":    //radio button
        case "checkbox": //checkbox
            if (!field.name) {
                break;
            }
            /* falls through */

        default: 
            //don't include form fields without names
            if (field.name.length) {
                parts.push(encodeURIComponent(field.name) + "=" + encodeURIComponent(field.value));
            }
    }
}
return parts.join("&");
}

现在在 process 函数中,我们可以做这样的事情:

process(e) {
    var data = serialize(form);
    handlePostRequest(data, handleResponse); //initiates ajax request and passes in callback function
    e.preventDefault(); //prevents default behavior of loading new page with results;
}

好的..哇。我们快完成了。

这是处理 ajax 调用的函数:

function handlePostRequest(data, callback) {
    var xhr = createXHR(),
        data = data;

    xhr.open("POST", "login/processLogin.php");
    xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");

    xhr.onreadystatechange = function() {
        if (xhr.readyState === 4) {
            var status = xhr.status;
            if ((status >= 200 && status < 300)) || status === 304) {
                 callback(xhr.responseXML);
            } else {
              alert("An error occurred");
            }
        }
    };
    xhr.send(data);
}

然后最后一个也是最后一个部分将是回调函数。

function handleResponse(response) {
    var xmlResponse = response,
        xmlDocumentElement = xmlResponse.documentElement,
        message = xmlDocumentElement.firstChild.data;

    document.getElementById("errorField").innerHTML = message;
}

它可能看起来势不可挡,但它是大多数发布请求所遵循的模式。老实说,这就是 jQuery 的魅力所在。但是,看看它是如何使用纯 JavaScript 完成的,总是一种很好的教育体验。我确定我可能错过了一些东西,所以如果有任何问题,请告诉我!我要去睡觉!

于 2013-04-19T03:31:37.380 回答
-1

我建议你使用 jQuery,它的代码更少,更容易这里有一个链接:http ://api.jquery.com/jQuery.ajax/

于 2013-04-19T02:13:09.487 回答
-2

我建议您使用 jQuery,而不是手动创建 XmlHttpRequest 对象,因为它设法解决了浏览器之间的一些兼容性问题,并使整个事情变得更简单。

使用 jQuery,您将能够使用以下方式执行请求:

$.post({
    url: "http://example.com/....",
    data: {"username": "your_user_here", "password": "your_password_here"},
    success: function(){
        alert('Success!');
    }
});

无论如何,那里有很多选项,而且这个主题很长,不适合 SO 答案,所以我建议您在这里查看 jQuery Ajax 文档:http: //api.jquery.com/category/ajax/

特别是这个:http ://api.jquery.com/jQuery.ajax/

更新

这里唯一的问题是 php 通常希望以表单编码格式接收数据,但是这样您的脚本将获得 json 数据..(因此,预计不能使用$_POST)与其他语言(python、nodejs、.. ) 这不是问题; 我不知道如何用 php 处理这个问题,但我非常有信心有办法做到这一点。当然,您可以回退到发送表单编码的数据,但 JSON 是当今这些事情的事实上的标准。

抱歉,我记错了,但是 jQuery 的默认行为是对 POST 数据进行 urlencode,因此在$_POST使用上面的代码执行请求时,您可以从 读取值。

于 2013-04-19T02:14:33.443 回答