如何强制jQuery验证检查数据库中的重复用户名?

3
我是一个有用的助手,可以将文本翻译成中文。
我加入了这个项目的中间部分,所以由于代码不规范,我需要重写一些代码。我正在使用 jQuery 1.6.1 和 Validate 1.8.1。
首先,这里是运行后端的 PHP 代码(dbquery.php):
include("../includes/dbconnection.php");
session_start();

$location='';
$action='';
if($_GET['action']=='')
    $action=$_POST['action'];
else
    $action=$_GET['action'];

if($action=='checkusername'){
    $error='';
    $username=$_GET['username'];
    // exclude denied account
    $checkuserquery=mysql_query("Select * from database_users as user LEFT OUTER JOIN  database_approval as approval on user.user_id=approval.approval_user_id  where (approval.approval_status IS NULL or approval.approval_status <> 4) and user_username='".$username."'");
    $checkuserresult=mysql_numrows($checkuserquery);
    if($checkuserresult>0) {
        $error = 'false';
    } else {
        $error = 'true';
    }
    echo $error;
} 

我正在尝试使用jQuery验证脚本来实时查询数据库中是否存在已有用户名。我要么遇到永远无法工作的情况,要么就始终返回给定的用户名已被占用。
我认为问题在于我无法获取用户名变量的输入值。当我在function(output)中创建alert(username)时,它什么也不返回。我的假设是.val()仅在页面加载时起作用,因此由于某种原因,我在输入框中输入的任何内容都无法工作。
以下是我从在线资源重写并复制的jQuery代码:
$(document).ready(function(){

$.validator.addMethod("checkAvailability",function(value,element){
    var username = $("#username").val();
    $.ajax({
          url: "dbquery.php",
          type: "GET",
          async: false,
          data: "action=checkusername&username="+username,
          success: function(output) {
                     return output;
         }
     });
},"Sorry, this user name is not available");

// jQuery Validation script
    $("#signup").validate( {
        rules: {
            username: {
                required: true,
                minlength: 5,
                checkAvailability: true // remote check for duplicate username
            },
        },
        messages: {
            username: {
                required: "Enter a username"
            }
        },
        submitHandler: function(form) {
            form.submit();
        }
    });

});

我只是一个jQuery的初学者,但是正在使用这段代码。我是否走在正确的轨道上,或者应该在rulesusername下使用remote:?我被告知由于我试图验证输入值的动态性质,remote方法将无法工作。

我遇到的另一个主要问题是,只有当数据库中已经存在用户名时,远程错误消息才会显示。不幸的是,它会出现无论dbquery.php返回true还是false。如果我尝试一个现有的用户名,它返回false,然后我重写一个返回true的新用户名,消息不会消失。同样地,当我写一个用户名并返回true时,我仍然会收到远程错误消息。

原始编码者引用了getXMLHTTP并使用了ActiveXObject。他编程的方法似乎有点过时,所以我正在尝试使代码更加现代化并清理它。

5/25 - 我正在编辑此内容,包括旧的原始JavaScript代码,该代码可以正常工作,但使用了我想摆脱的过时方法(我已经删除了以下代码,并用上面的jQuery替换了它

function getXMLHTTP() { //function to return the xml http object
    var xmlhttp=false;    
    try{
        xmlhttp=new XMLHttpRequest();
    }
    catch(e)    {        
        try{            
            xmlhttp= new ActiveXObject("Microsoft.XMLHTTP");
        }
        catch(e){
            try{
            xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
            }
            catch(e1){
                xmlhttp=false;
            }
        }
    }

    return xmlhttp;
}
//validate username
function validateUsername(username){
    var strURL="dbquery.php?action=checkusername&username="+username;
    var req = getXMLHTTP();        
    if (req) {            
        req.onreadystatechange = function() {
            if (req.readyState == 4) {
                // only if "OK"
                if (req.status == 200) {          
                    if(req.responseText=='notavailable'){
                        document.getElementById("errorusername").style.display="block";
                        document.getElementById("errorusername").innerHTML="<div id=\"errors\"><strong>"+username+"</strong> is already taken by another user.</div>";
                        error = true;
                    }
                    else{
                        error = false;
                        document.getElementById("errorusername").style.display="none";   
                    }

                } else {
                    alert("There was a problem while using XMLHTTP:\n" + req.statusText);
                }
            }                
        }            
        req.open("GET", strURL, true);
        req.send(null);
    }     
}
5个回答

5

检查验证函数何时被调用,username的值是什么以及output的值是什么:它是true还是"true"

我猜是后者:一个字符串,所以你可以这样做:

return output === "true" ? true : false; // I sincerely recommend using === here

如果你使用return "false";,它会被视为true,因为这是一个非空字符串 - 动态语言的优势!:/

关于remote的示例:

$("#signup").validate( {
    rules: {
        username: {
            required: true,
            minlength: 5,
            remote: {
                url: "dbquery.php",
                type: "get",
                data: {
                    action: function () {
                        return "checkusername";
                    },
                    username: function() {
                        var username = $("#username").val();
                        return username;
                    }
                }
            }
        }
    },
    messages: {
        username: {
            required: "Enter a username"
        }
    },
    submitHandler: function(form) {
        form.submit();
    }
});

要设置自定义错误消息,您的PHP文件必须返回消息而不是false,因此在您的PHP文件中使用echo "抱歉,此用户名不可用"


@frits-van-campen 我认为我的主要目标是只在用户名的值返回“false”时才显示错误消息。我似乎已经纠正了最初的问题,并在需要时返回了“true”和“false”。 - micah
@frits-van-campen 上面的代码无论用户名返回 true 还是 false,都会不断地返回 抱歉,此用户名不可用。我希望它只在返回 false 时显示,并在返回 true 时消失。 - micah
你确定它是 true 而不是 "true" 吗?通常情况下,Firebug在记录字符串时不会添加引号,我可以确定alert也不会。尝试使用我发布的这一行代码:return output === "true" ? true : false; - Halcyon
@frits-van-campen 这真是令人沮丧。使用 Validator 做我想做的事情基本上是不可能的吗?老实说,我对 jQuery 是个新手,我以为这些东西会很好用,但这对我来说却是最大的头疼。 - micah
@frits-van-campen 我需要问的另一个问题是,我认为我也可以在电子邮件上使用完全相同的方法。由于某种原因,“@”变成了“%40”。这不会导致验证失败,但这是发生的原因吗? - micah
显示剩余10条评论

2
在添加 addMethod 时,您应该从服务器端返回 truefalse
并且该值也必须从 addMethod 中返回。
例如:
$.validator.addMethod("checkAvailability",function(value,element){
    var parameter="action=checkusername&username="+username;
    $.ajax({
          url: "dbquery.php",
          type: "POST",
          async: false,
          data: parameter
          success:function(output)
                 {
                    return output
                 }
     });
},"Sorry, this user name is not available");

@mahesh 我不确定如何编写警告!我对此还比较陌生。是这样吗?function alert(output) 因为似乎不起作用。 - micah
@mahesh 不好意思,我尝试的每个用户名都已被使用。 - micah
你能否尝试使用“return true”来检查一下?这样是否会显示验证信息? - Mahesh KP
@mahesh,我已经删除了用户名的消息,但是没有任何改变。我仍然收到相同的验证错误消息。 - micah
1
@mahesh,我非常感激你所做的一切。即使没有其他收获,我也学到了很多东西。如果我找到了验证你所说的话的方法,我一定会留下另一个评论。 - micah
显示剩余47条评论

1

我曾经遇到过同样的问题,但是我发现最简单的解决方案就是通过PHP将其编码为JSON后返回true或false。

if ($users->username_exists())
{
    echo json_encode(FALSE);
}else{
    echo json_encode(TRUE);
}

0
在您的服务器端脚本中,尝试返回truefalse而不是availablenotavailable,因为这两个字符串都等同于true

@minboost 是的,我确实尝试过这个方法,但结果并没有改变。感谢您的建议。 - micah
你检查过你的PHP页面是否正确返回了吗?并且你确认你正在返回字符串'true'和'false'吗?如果你尝试echo布尔值,它会返回1或(空白)。 - minboost
@minboost 是的,原始的 JS 代码可以正常工作,但很混乱。因此,我确信 PHP 代码功能正常,但新的 jQuery 版本可能需要进行某些更改。我只是还不知道是什么。 - micah
1
我会使用 remote: 而不是创建一个新的方法。该方法可能在 ajax 完成之前返回一个值(NULL)。使用 ajax 的 JS 函数在继续处理之前不会等待结果。 - minboost
此外,您的PHP文件容易受到SQL注入攻击。 - minboost
@minboost 阅读后,我同意remote:可能是正确的方法,但我仍然在尝试解决这个脚本无法正常工作的问题。我该如何编写与远程相同的ajax方法?最大的问题是在remote:函数中包含数据参数。另外,我该如何重写它以防止SQL注入?那比我知道如何纠正更高级。感谢您的建议! - micah

-1

我的代码:

$( "#myform" ).validate({
  rules: {
    EMAIL: {
      remote: {
        type: "post",  
        url: "checkMail.php",           
        data:{checkUsername:function(){return $("#EMAIL").val()}            
        }
      }
    }
  },messages:{EMAIL:{remote: "Already taken!"}}
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接