2016-04-14 33 views
1

我正在處理聯繫表單。
當用戶鍵入輸入字段時,我檢查輸入以查看其輸入是否有效(在名爲validateInput()的函數中使用javascript),並在引用彈出窗口無效時彈出。我正在驗證聯繫表單。我是否做了太多的過濾?

姓氏字段和主題字段不是必需的。我有一個問題,我的正則表達式是否適合這些?(在window.onload中定義)

無論如何,如果用戶提交表單,則會進行進一步測試以查看該數據是否有效。(儘管它是已經檢查過,但以防萬一他們忽略了popover)。

如果按下提交後數據確實有效,那麼通過xmlhttp請求將表單數據發送到contact_handler.php。 當到達那裏,檢查發佈數據是否被設置。如果它被設置,那麼我在不同的發佈數據上使用filter_var函數。之後,我使用preg_replace將名稱和消息字段過濾爲有限的一組字符。

然後我調用我在contact_functions.php中定義的saveContactInfo()函數,它將數據插入數據庫。 我的問題是:我是否做了太多的數據過濾?有沒有做太多這樣的事情?我只是想確保數據是安全的。

這是我的代碼。有很多的意見,因爲它是一個大學分配...

contact.html

<form> 
    <div class="row"> 
     <div class="form-group"> 
        <label for="firstname">Firstname*</label> 
      <input type="text" class="form-control" id="first-name" maxlength="30" data-trigger="manual" data-placement="top" data-content="Must be at least 3 characters long, and must only contain letters and the following characters .'-" autofocus> 
       </div> 
     <div class="form-group"> 
        <label for="lastname">Lastname</label> 
         <input type="text" class="form-control" id="last-name" maxlength="30" data-trigger="manual" data-placement="top" data-content="Must only contain letters and the following characters .'-" > 
       </div> 
     <div class="form-group"> 
      <label for="email">Email*</label> 
        <input type="email" class="form-control" id="email" maxlength="254" data-trigger="manual" data-placement="top" data-content="Must be a valid e-mail address."> 
       </div> 
     <div class="form-group"> 
         <label for="subject">Subject</label> 
         <input type="text" class="form-control" id="subject" maxlength="200" data-trigger="manual" data-placement="top" data-content="Must only contain letters, numbers and the following characters .,'-?!=&quot;()"> 
       </div>    
       <div class="form-group"> 
         <label for="message">Message*</label> 
         <textarea id="message" class="form-control" maxlength="1000" data-trigger="manual" data-placement="top" data-content="A message with a minimum of 15 characters is required. Must only contain letters, numbers and characters such as .,'-?!=&quot;()" rows="4"></textarea> 
       </div> 
     <div id="form-message" class="form-group"> 
      <p></p> 
     </div> 
     <!--give the button an id of submitButton so we can add a click event listener to it in our javascript--> 
       <button id="submitButton" type="button"class="btn btn-orange"><i class="fa fa-envelope-o"></i> Submit</button> 

    </div>     
</form> 

的JavaScript在contact.html

<script> 

//declare global variables 
var firstNameRegex; 
var lastNameRegex; 
var subjectRegex; 
var emailRegex; 
var messageRegex; 
var xmlhttpContact; 

window.onload = function(){ 
    /*this function is implemented after the page is fully loaded. 
    *the first name field should be a minimum of 3 characters and should only contain letters and certain special characters 
    *such as full stop, apostrophe, and hyphen. 
    */ 
    firstNameRegex = /^([A-Za-z .'-]{3,})$/; 

    /*The last name field should be a minimum of 0 characters as it is not a required field, 
    *and should only contain letters and certain special characters such as full stop, apostrophe, and hyphen. 
    */ 
    lastNameRegex = /^([A-Za-z .'-]{0,})$/; 


    /*The subject field is optional so can therefore be a minium of 0 characters. 
    *If any characters are entered in this field they should only be letters, numbers or certain special characters 
    *limited to the full stop, apostrophe, and hyphen characters. 
    */ 
    subjectRegex = /^([A-Za-z0-9 .,'-?!="()]{0,})$/; 

    //The email address entered by the user, will be tested against the following regular expression. 
    //This regular expression for an email address is recommended in the W3C HTML5 specification. (See reference at top of this page.) 
    emailRegex = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-][email protected][a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/; 

    //The message entered by the user, will be tested against the following regular expression. 
    //There is a minimum of 15 characters required in the message. 
    messageRegex = /^([A-Za-z0-9 .,'-?!="()]{15,})$/; 


    //add a 'click' event listener to our submit button. When the button is pressed we will call the subitForm() function 
    document.getElementById('submitButton').addEventListener('click', submitForm, false); 

    //call the validateInput() function which we have defined below and pass the id of the input fields and their corresponding 
    //regular expression values as parameters. 
    validateInput('first-name', firstNameRegex); 
    validateInput('last-name', lastNameRegex); 
    validateInput('subject', subjectRegex); 
    validateInput('email', emailRegex); 
    validateInput('message', messageRegex); 

    //remove the form error and success messages when 'keypress' or 'focus' events occur on input or textarea fields. 
    removeFormMessages(); 
} 

function validateInput(inputID, regularExpression){ 
    /*This is a function which takes in the id of an input field or textarea and a regular expression as parameters. 
    *In this function we test the value of the input field (or textarea) against the regular expression 
    *which we have defined for that input type to make sure the input is valid. 
    *For example if we are taking in the users 'first name' as input, then we will test this against the 
    *regular expression we have defined for a valid first name (in the indow.onload function). 
    *If it is NOT valid then we display a popover message to the user. 
    *If input IS valid then we hide the popover. This gives immediate feedback to the user during the process of filling 
    *out the form. 
    */ 

    //we listen for the following events on the input field or textarea that was passed as a parameter. 
    //'keyup', 'keypress', 'blur', 'change' 
    //The input entered in that field is checked for validity when these events occur. 
    //If it is not valid, then the popover with error message is displayed until input is validated. 

    $('#' + inputID).on('keyup keypress blur change', function(){ 
     //store the value of our input field into a javascript variable called inputValue 
     var inputValue = document.getElementById(inputID).value; 

     //Now we test our inputValue against the appropriate regular expression (which we took in as a parameter). 
     //the javascript test() function which we use here will return true if the input matches the regular expression 
     //and false if not. 
     //We store the boolean result into the variable isInputValid 
     var isInputValid = regularExpression.test(inputValue); 

     if(!isInputValid){ 
     //If input is not valid go here 
      if(!$(this).hasClass('isShowing')){ 
       //if our popover error does not have class isShowing then do the following 
       //show popover and add class isShowing to the element so that we know what state it is in. 
       $(this).popover('show'); 
       $(this).addClass('isShowing'); 
      } 
      //else if our popover error is already showing then leave it showing (ie do nothing here). 
     }else{ 
     //If input is valid go here 
      if($(this).hasClass('isShowing')){ 
       //if our popover error has class isShowing then do the following 
       //hide popover and remove isShowing class so we know it is hidden now 
       $(this).popover('hide'); 
       $(this).removeClass('isShowing'); 
      } 
      //else if our popover error is already hidden then leave it hidden. 
     } 
    }); 
} 
function removeFormMessages(){ 
    /*This function listens for a 'keypress' or a 'focus' event on input and textarea fields 
    *and when it detects these events it hides the form-message paragraph. 
    *We do this because, If a user has submitted the form and then been notified that the 'form is invalid' 
    *and goes back to change his/her input then we assume they have seen the error message 
    *so we delete it so that the next time they are notified of something it will be easier to see. 
    */ 
    $('input, textarea').on('keypress focus', function(){ 
     $("#form-message p").hide(); 
     $("#form-message p").removeClass('animated').removeClass('bounce'); 
     $("#form-message p").html(''); 
    }); 
} 
function hideAllPopovers(){ 
    /*this function hides all popovers that are currently showing on input fields or textareas. 
    *We will call this function after the form is submitted, if all fields are valid. 
    */ 
    $('input, textarea').popover('hide'); 
    $('input, textarea').removeClass('isShowing'); 
} 
function submitForm(){ 
    //get the values of all input and textarea fields in the contact form 
    var firstName = document.getElementById('first-name').value; 
    var lastName = document.getElementById('last-name').value; 
    var email = document.getElementById('email').value; 
    var subject = document.getElementById('subject').value; 
    var message = document.getElementById('message').value; 

    //we need to check the validity of the input values in case the user has ignored our popover error messages 
    //therefore test (again) the values the user entered against regular expressions which we defined earlier for different types of input. 
    //and store the boolean results into variables. 
    var isfirstNameValid = firstNameRegex.test(firstName); 
    var islastNameValid = lastNameRegex.test(lastName); 
    var isSubjectValid = subjectRegex.test(subject); 
    var isEmailValid = emailRegex.test(email); 
    var isMessageValid = messageRegex.test(message); 

    if((!isfirstNameValid) || (!islastNameValid) ||(!isEmailValid) ||(!isSubjectValid) || (!isMessageValid)){ 
     //If any of the values entered to the input fields are invalid then show an error message to the user. 
     //And do not allow the form to be submitted 
     //We use the error-text class for red text. 
     $("#form-message p").html('<span class="error-text"><i class="fa fa-exclamation-triangle"></i> The form is not valid!</span>'); 
     $("#form-message p").show(); 
     $("#form-message p").addClass('animated').addClass('bounce'); 
    }else{ 
     //If form input is valid then firstly hide any popovers which are showing 
     hideAllPopovers(); 

     //then we create a new xmlhttp request. 
     xmlhttpContact = createXHR(); 

     xmlhttpContact.onreadystatechange = contactCallback; //when the response comes back call the contactCallback function 
     //Send our form values to the contact_handler.php page by POST 
     xmlhttpContact.open("POST", "contact_handler.php" ,true); 
     xmlhttpContact.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); 
     //send our variables to the contact_handler.php page by POST 
     xmlhttpContact.send("firstName=" + firstName + "&lastName=" + lastName + "&email=" + email + "&subject=" + subject + "&message=" + message); 

    } 
} 

function contactCallback(){ 
    //this function will be called when we receive a response back from the xmlhttp request. 
    if(xmlhttpContact.readyState == 4 && xmlhttpContact.status == 200){ 

     //store the response text into a variable called message. 
     var message = xmlhttpContact.responseText; 

     //clear any text in the input fields. 
     $('input, textarea').val(''); 
     //insert our message to the form-message paragraph tag 
     $("#form-message p").html('<i class="fa fa-check"></i> ' + message); 
     $("#form-message p").show(); 
     //we use the bootstrap animation classes to create an animation on the message text. 
     $("#form-message p").addClass('animated').addClass('bounce'); 

    } 
} 
</script> 

contact_handler.php

<?php 
//check if all the required fields are set 
if(isset($_POST['firstName']) && isset($_POST['email']) && isset($_POST['message'])){ 
    //collect the post data if the contact form has been submitted and store it into local variables 

    //Remove all HTML tags from $_POST["firstName"] and store it into variable $firstName 
    $firstName = filter_var($_POST["firstName"], FILTER_SANITIZE_STRING); 

    if(isset($_POST['lastName'])){ 
     //check if lastName isset before filtering it. 
     //Remove all HTML tags from $_POST["lastName"] and store it into variable $lastName 
     $lastName = filter_var($_POST["lastName"], FILTER_SANITIZE_STRING); 
    } 

    //Remove illegal characters from $_POST["email"] 
    $email = filter_var($_POST["email"], FILTER_SANITIZE_EMAIL); 

    if(isset($_POST['subject'])){ 
     //check if subject isset before filtering it. 
     //Remove all HTML tags from $_POST["subject"] and store it into variable $subject 
     $subject = filter_var($_POST["subject"], FILTER_SANITIZE_STRING); 
    } 

    //Remove all HTML tags from $_POST["message"] and store it into variable $message 
    $message = filter_var($_POST["message"], FILTER_SANITIZE_STRING); 

    //do further filtering with preg_replace for extra security. 
    $firstName = preg_replace("#[^A-Za-z .'-]#i", "", $firstName); //filter everything but letters and a few special characters. 
    $lastName = preg_replace("#[^A-Za-z .'-]#i", "", $lastName); //filter everything but letters and a few special characters. 
    $subject = preg_replace("#[^A-Za-z0-9 .,'-?!=\"()]#i", "", $subject); //filter everything but numbers, letters and a few special characters. 
    $message = preg_replace("#[^A-Za-z0-9 .,'-?!=\"()]#i", "", $message); //filter everything but numbers, letters and a few special characters. 


    //store the boolean result of saveContactInfo function into a variable called $messageSent 
    $messageSent = saveContactInfo($firstName, $lastName, $email, $subject, $message, $pdoConnection);//this method is defined in contact_functions.php 
    if($messageSent){ 
     //if saveContactInfo returns true then we know the data has been entered to the database so we inform the user that 
     //the message has been sent. This message will be echoed back to our ajax callback method in contact.html 
     //where we will insert it to the HTML. 
     echo 'Your Message has been sent!!'; 
    } 
} 
?> 
底部

contact_functions.php

<?php 
function saveContactInfo($firstName, $lastName, $email, $subject, $message, $pdoConnection){ 
    $messageTime = time(); //Get timestamp of current time and store it into a variable 

    try{ 
     $query ="INSERT INTO contact_info (firstName, lastName, email, subject, message, messageTime) VALUES (:firstName, :lastName, :email, :subject, :message, :messageTime)"; 
     $statement = $pdoConnection->prepare($query); 
     $statement->bindValue(':firstName', $firstName, PDO::PARAM_STR); 
     $statement->bindValue(':lastName', $lastName, PDO::PARAM_STR); 
     $statement->bindValue(':email', $email, PDO::PARAM_STR); 
     $statement->bindValue(':subject', $subject, PDO::PARAM_STR); 
     $statement->bindValue(':message', $message, PDO::PARAM_STR); 
     $statement->bindValue(':messageTime', $messageTime, PDO::PARAM_STR); 
     $statement->execute(); 
     return true; 
    }catch(PDOException $e){ 
     //throw new pdoDbException($e); 
     return "Error message " . $e->getMessage(); 
    } 
} 
?> 
+2

如果它能正常工作,它取決於你想要你的驗證有多徹底。 –

+4

那些名字叫「Lu/Xu」的人呢?非拉丁符號呢?消息不能包含更大/更小的標誌? –

+1

最好的做法是在客戶端和服務器端進行驗證。如果您的驗證無意中改變了數據並使其無效或無法識別,則這只是「太多」。如果它發生巨大變化,你會想要通知用戶實際完成的數據。 – larsAnders

回答

1

有沒有做這麼多事情?

當然可以,任何事情都可以做到荒謬的次數,變得「太多」。

我是否做了太多的數據過濾?

我會說是的,但問題是相當空洞的。我將把它解釋爲'我正在做最有意義的驗證嗎?',你正在做太多的驗證,因爲你在前端和後端進行驗證,對於那些只是在查詢字符串上的內容,contact_handler.php你可能只是想在後端做所有事情,因爲任何人都可以繞過你的javascript並手工輸入查詢字符串。

這並不意味着不在前端進行驗證。在前端執行一種類型的驗證,以確保填寫所有表單的字段。

所有對長度和內容的驗證我在後端執行,發回任何對xhr請求的響應中的錯誤。當然,重新驗證查詢字符串中字段的存在是必須的,因爲任何人都可以手動發送具有意外查詢字符串的請求。

我要避免前端驗證,直到後端堅如磐石。

+0

我在做前端驗證以獲得更好的用戶體驗。這些餡餅會讓他們立即反饋他們所輸入內容的有效性。它沒有被查詢字符串發送 - 它的發佈數據...感謝您的意見。 – Sarah

+1

對不起,它使用郵件正文,GET使用qs。 – MatUtter