Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/425.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/285.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 我的注册码允许同一封电子邮件注册两次(仅当表单连续提交多次且速度非常快时)_Javascript_Php_Html_Mysql_Database - Fatal编程技术网

Javascript 我的注册码允许同一封电子邮件注册两次(仅当表单连续提交多次且速度非常快时)

Javascript 我的注册码允许同一封电子邮件注册两次(仅当表单连续提交多次且速度非常快时),javascript,php,html,mysql,database,Javascript,Php,Html,Mysql,Database,我已经用HTML、Javascript和php编写了一些注册代码。 注册过程(更高级别)如下: 用户: 1.在HTML表单中输入他们的电子邮件、姓名和密码(两次)。 2.他们按“创建帐户” 3.然后在“我的用户”表中搜索他们的电子邮件,以查看是否 存在。 4.如果存在,则告知他们已注册,并提供登录屏幕的链接。 5.如果该电子邮件不存在,则会将其(连同其他用户详细信息)插入到我的数据库中的users表中 我的代码很好地实现了这一点,但是在测试时我发现了一个错误。如果用户以非常快的速度多次按“创建帐

我已经用HTML、Javascript和php编写了一些注册代码。 注册过程(更高级别)如下:

用户:
1.在HTML表单中输入他们的电子邮件、姓名和密码(两次)。
2.他们按“创建帐户”
3.然后在“我的用户”表中搜索他们的电子邮件,以查看是否 存在。
4.如果存在,则告知他们已注册,并提供登录屏幕的链接。 5.如果该电子邮件不存在,则会将其(连同其他用户详细信息)插入到我的数据库中的users表中

我的代码很好地实现了这一点,但是在测试时我发现了一个错误。如果用户以非常快的速度多次按“创建帐户”,则允许同一电子邮件地址注册两次。我能做些什么来阻止这一切吗

这是我的代码:
JQuery/Javascript

$("#registration_form").on("submit", function(e){
    //this is called when the form is submitted i.e when "create account" is pressed
    e.preventDefault();

    var registration_email = $('#registration_email').val();  
    var registration_password = $('#registration_password').val(); 
    var registration_password_confirmation = $('#confirm_registration_password').val(); 
    var registration_display_name = $('#registration_display_name').val(); 

    //validate fields and check if passwords match.
    //all values have passed validation testing therefore make ajax request

    var params = { 'registration_email' : registration_email, 'registration_password' : registration_password , 'registration_display_name' :  registration_display_name, 'app_root_url':app_root_url}; 

        $.ajax({
        url: app_root_url + 'login_registration/registration_processing.php',
        data: JSON.stringify(params), 
        type: "POST",
        dataType: "json",
        contentType: "application/json;charset=utf-8",

            success: function(data){
            var result = data;

            var emailAlreadyExists = result.email_already_exists; 
            if(emailAlreadyExists){
                //email already exists in our database and therefore the user is already registered so should use the login form

                displayError('registration_feedback_message', 'This email already exists in the system. If you already have an account please <a href="#page-login">login here!</a>');

            }else{
                //email does not already exist in our database

            }               

        }//end success
    });//end ajax


});
registerUser函数(在app_functions.php中)

我能想到的一个解决方案是在“createaccount”按钮上放置一个计时器,这样多个ajax请求就不能如此接近了

编辑 在阅读了您的一些解决方案后,我正在研究如何使电子邮件领域独一无二。谢谢 我在phpMyAdmin工作,所以它是否只需按“unique”(在图像中突出显示)即可简单

编辑2 我尝试将电子邮件创建为唯一密钥,但出现以下错误:

编辑3
为了解决上面的错误(在编辑2中),我将电子邮件地址字段的排序规则从utf8mb4_unicode_ci更改为utf8_unicode_ci,然后我再次尝试按“unique”,结果成功了。谢谢大家

您可以向数据库中的电子邮件字段添加唯一约束。这样,如果您尝试插入一封已经存在的电子邮件,它将失败。

您已在else case和not if case中返回了数据。现在有两个选项。 不在else块中返回数据,而是在else块或 如果情况相同,则返回数据


这会导致当它找到电子邮件id但未返回时,如果您进行检查,则该id将为false,因此它允许注册用户为两个不同的帐户使用相同的电子邮件id

使数据库中的电子邮件字段唯一。我不推荐PK,因为用户可能想更改他们的电子邮件地址

我始终建议在服务器和客户端上进行验证

在这种情况下,正如大家所提到的,在服务器(数据库)中,您应该在电子邮件字段中定义一个,这样就不会出现重复的电子邮件


我还建议在第一次单击“创建帐户”按钮后单击它。您甚至可以将按钮的名称更改为“…请稍候”,以指示操作正在执行。当您从服务器获得响应(成功或失败)时,您可以再次启用它。这将首先避免对服务器的任何不必要的连续调用。

防止重复的正确方法是在数据库中使用唯一的约束/索引,而不是在应用程序中使用竞争查询。显然是的,就这么简单,但如果您害怕,制作一个表的副本,并在副本上进行测试,然后在另一个表上进行测试。我将userID作为主键。我是否可以在不更改主键的情况下向电子邮件字段添加唯一约束?还是我也需要重新考虑我的主键?谢谢您不必更改您的主键,但请确保您确实需要userID。好的,非常感谢。你能看到我的编辑吗?那么我是否只需要在phpMyAdmin中的表中选择“unique”(在上图中突出显示)?是的,您只需要这个。太好了!谢谢你的帮助。谢谢你指出这一点。我现在在registerUser函数中看到了它。谢谢你的建议。我会像你说的那样禁用按钮。
include_once '../includes/app_functions.php';
$app_root_url = filter_var($json->app_root_url, FILTER_SANITIZE_URL);
$email = filter_var($json->registration_email, FILTER_SANITIZE_EMAIL); 
$password = filter_var($json->registration_password, FILTER_SANITIZE_STRING);
$display_name = filter_var($json->registration_display_name, FILTER_SANITIZE_STRING);
//more data filtering is performed here

$userPrivilegeID = 1; //basic user privilege
$userHasPassword = 1; //boolean 1 or 0

$profileImage = "images/profile_images/blank-avatar.png"; 

$results = registerUser($password, $email, $isAvatarImage, $profileImage, $userPrivilegeID, $display_name, $userHasPassword, $pdoConnection);

//create an array to store all values that we want to send back to the client side.
$data = array();
if($results['exception_occurred'] == true){
        $data['exception_occurred'] = true;
        $data['exception_message'] = $results['exception_message']; 
        echo json_encode($data);

}else{
        $data['exception_occurred'] = false;
        if($results['email_already_exists'] == true){
            //email already exists. user is already registered and therefore has a password
            //need to show error to user to say they are already registered and should use the login form.

            $data['email_already_exists'] = true;
            echo json_encode($data);

        }else{
            //email didnt exist so they have been registered
            $data['email_already_exists'] = false;
            //create an array which we will encrypt as our JWT token
            $token = array();
            $token['userID'] = $results['user_id'];
            $token['email'] = $email;

            $data['userID'] = $results['user_id'];
            $data['user_is_subscriber'] = true;
            $data['valid_user'] = true;
            $data['userDetails'] = getProfile($results['user_id'], $pdoConnection);

            $data['usertoken'] = JWT::encode($token, 'secret_server_key');
            //echo data back to ajax request on client side
            echo json_encode($data);
        }
}
function registerUser($password, $email, $isAvatarImage, $profileImage, $userPrivilegeID, $display_name, $userHasPassword, $pdoConnection){
    $data = array();
    try{
        $data['exception_occurred'] = false;
        //first check if that email already exists just in case
        $query = "SELECT COUNT(userID) FROM users WHERE emailAddress=:emailAddress";
        $statement = $pdoConnection->prepare($query);
        $statement->bindValue(':emailAddress', $email, PDO::PARAM_STR);
        $statement->execute();  
        $rowCount = $statement->fetchColumn(0);
        if($rowCount > 0){
            //email already exists. user is already registered and therefore has a password
            //need to show error to user to say they are already registered and should use the login form.
            $data['email_already_exists'] = true; 
            return $data;
        }else{
            $data['email_already_exists'] = false;

            $hashedPassword = password_hash($password, PASSWORD_DEFAULT, ['cost' => 12]);
            $query = "INSERT INTO users (emailAddress, password, isAvatarImage, profileImage, userPrivilegeID, displayName, userHasPassword) VALUES (:emailAddress, :password, :isAvatarImage, :profileImage, :userPrivilegeID, :displayName, :userHasPassword)";
            $statement = $pdoConnection->prepare($query);
            $statement->bindValue(':emailAddress', $email, PDO::PARAM_STR);
            $statement->bindValue(':password', $hashedPassword, PDO::PARAM_STR);
            $statement->bindValue(':isAvatarImage', $isAvatarImage, PDO::PARAM_INT);
            $statement->bindValue(':profileImage', $profileImage, PDO::PARAM_STR);
            $statement->bindValue(':userPrivilegeID', $userPrivilegeID, PDO::PARAM_INT);
            $statement->bindValue(':displayName', $display_name, PDO::PARAM_STR);
            $statement->bindValue(':userHasPassword', $userHasPassword, PDO::PARAM_INT);
            $statement->execute();
            $data['user_id'] = $pdoConnection->lastInsertId();
            return $data;
        }
    }catch(PDOException $e){
        //throw new pdoDbException($e); 
        $data['exception_occurred'] = true;
        $data['exception_message'] =  $e->getMessage();
        return $data;
    }
}