Jump to content


Photo
- - - - -

Javascript XHR SPA forms.


  • Please log in to reply
4 replies to this topic

#1 fiveworlds

fiveworlds

    Primate

  • Senior Members
  • 1,525 posts
  • LocationSomewhere on the internet

Posted 23 December 2016 - 07:49 PM

I am trying to write a function which will send data to my server, get a response and set secure cookies without having to reload the page. I'm not sure if I am using it correctly though. Everything is fine apart from trying to upload files to the server. I looked it up on stackoverflow http://stackoverflow...-xmlhttprequest and one response mentioned I should use FormData https://developer.mo...rmData/FormData and parse it as raw data on the server http://php.net/manua...rawpostdata.php but I'm not sure how to do that properly.
 

<script>
function sendform(data,action,method,enctype){
  var xhr = new XMLHttpRequest();
  xhr.open(method, action, true);
  xhr.setRequestHeader("Content-type", enctype);
  xhr.credentials = true;
  xhr.send(data);
  xhr.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
        document.getElementById("test").innerHTML = this.responseText;
        return false;       
    }
  }
}
function setcookie(id) {
    form = document.getElementById(id);
    action = form.action;
    method = form.method;
    enctype = form.enctype;
    var data = "";
    for(var i=0, inputs = form.getElementsByTagName("input"); i<inputs.length; i=i+1) {
        if(!(inputs[i].type === "checkbox" && inputs[i].checked!="checked")||(inputs[i].type === "radio" && inputs[i].checked!="checked")){
            data = data+inputs[i].name+"="+inputs[i].value +"&";
        }
    }
    for(var i=0, inputs = form.getElementsByTagName("textarea"); i<inputs.length; i=i+1) {
        data = data+inputs[i].name+"="+inputs[i].value +"&";       
    }
   
    for(var i=0, inputs = form.getElementsByTagName("select"); i<inputs.length; i=i+1) {
        data = data+inputs[i].name+"="+inputs[i].options[inputs[i].selectedIndex].value +"&";       
    }
    sendform(data,action,method,enctype);
   
    return false;
   
}
   
function validatepassword(){
    document.getElementById("test").innerHTML = document.getElementById("cpassword").value;
    if(document.getElementById("password").value===document.getElementById("cpassword").value){
        document.getElementById("validatepassword").style.display = "none";
        document.getElementById("password").style.border = "none";
        document.getElementById("cpassword").style.border = "none";
    }else if(document.getElementById("cpassword").value===""){
       
    }
    else{
        document.getElementById("validatepassword").style.display = "initial";
        document.getElementById("password").style.border = "2px solid red";
        document.getElementById("cpassword").style.border = "2px solid red";
    }
}
</script>
<script type="text/javascript" src="countries.js"></script>
<div id="test"></div>
<form method="post" enctype="application/x-www-form-urlencoded" action="cookie.php" id="login" onsubmit="return setcookie(this.id)">
    Username:<input id="username" type="text" name="username" /><br/>
    Password:<input id="password" onblur="validatepassword()" type="password" name="password" /><br/>
    Confirm Password:<input id="cpassword" onblur="validatepassword()" type="password" name="cpassword" /><br/>
    <label id="validatepassword" style="display:none">The passwords don't match</label><br/>
    Select Country:   <select onchange="print_state('state',this.selectedIndex);" id="country" name ="country"></select><br/>
    City/District/State: <select name ="state" id ="state"></select>
   
    <textarea name="comments" ></textarea>
    <button type="submit" >Submit</button>
</form>
<script language="javascript">print_country("country");</script>

 
 

<?php
$cookie_name = "username";
$cookie_value = "John Doe";
setcookie($cookie_name, $cookie_value, time() + (86400 * 30), "/", "127.0.0.1",true,true);
echo $_POST["password"];
?>​

  • 0

#2 Sensei

Sensei

    Scientist

  • Senior Members
  • 3,093 posts

Posted 23 December 2016 - 08:14 PM

https://developer.mo...eadystatechange
xhr.onreadystatechange should be prior xhr.send();

In the example above there are THREE =, you have only two.
"if(xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) {"


I wouldn't use the same function name as already existing in native PHP (setcookie())..

Edited by Sensei, 23 December 2016 - 08:21 PM.

  • 0

#3 fiveworlds

fiveworlds

    Primate

  • Senior Members
  • 1,525 posts
  • LocationSomewhere on the internet

Posted 23 December 2016 - 08:35 PM

I wouldn't use the same function name as already existing in native PHP (setcookie())..          ​

 

 

Yeah I originally made it just to set secure httpOnly cookies on login without reloading the page.

 

 

https://developer.mo...eadystatechange
xhr.onreadystatechange should be prior xhr.send();

In the example above there are THREE =, you have only two.
"if(xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) {"

 

 

True but neither were causing problems at the moment.


  • 0

#4 Sensei

Sensei

    Scientist

  • Senior Members
  • 3,093 posts

Posted 23 December 2016 - 08:45 PM

Try using alert()
http://www.w3schools...t_win_alert.asp
to see which code is executed, and which not.

f.e.
 

function sendform(data,action,method,enctype){
 alert( "sendform" );
 var xhr = new XMLHttpRequest();
 xhr.open(method, action, true);
 xhr.setRequestHeader("Content-type", enctype);
 xhr.credentials = true;
 xhr.onreadystatechange = function() {
  alert( "onreadystatechange 1" );
  if(xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) {
   alert( "onreadystatechange 2" );
  }
 }
 xhr.send(data);
}

You used "this.readyState", "this.status"

but they are

if(xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) {
in examples..


Edited by Sensei, 23 December 2016 - 08:48 PM.

  • 0

#5 fiveworlds

fiveworlds

    Primate

  • Senior Members
  • 1,525 posts
  • LocationSomewhere on the internet

Posted 23 December 2016 - 09:03 PM

Warning: Missing boundary in multipart/form-data POST data in Unknown on line 0
------WebKitFormBoundaryvoBiVkolzq5ctA40 Content-Disposition: form-data; name="username" test ------WebKitFormBoundaryvoBiVkolzq5ctA40 Content-Disposition: form-data; name="password" qaz ------WebKitFormBoundaryvoBiVkolzq5ctA40 Content-Disposition: form-data; name="cpassword" qaz ------WebKitFormBoundaryvoBiVkolzq5ctA40 Content-Disposition: form-data; name="country" Anguilla ------WebKitFormBoundaryvoBiVkolzq5ctA40 Content-Disposition: form-data; name="state" Anguilla ------WebKitFormBoundaryvoBiVkolzq5ctA40 Content-Disposition: form-data; name="test"; filename="Untitled.png" Content-Type: image/png PNG  IHDR

This is what is recieved by my server when I print out formData.

<?php
$cookie_name = "username";
$cookie_value = "John Doe";
setcookie($cookie_name, $cookie_value, time() + (86400 * 30), "/", "127.0.0.1",true,true);
echo $rawData = file_get_contents("php://input");
?>
<script>
function sendform(data,action,method,enctype){
  var xhr = new XMLHttpRequest();
  xhr.open(method, action, true);
  xhr.setRequestHeader("Content-type", enctype);
  xhr.credentials = true;
  xhr.onreadystatechange = function() {
    if (this.readyState === 4 && this.status === 200) {
        document.getElementById("test").innerHTML = this.responseText;
        return false;       
    }
  }
  xhr.send(data);
}
function setcookie(id) {
    form = document.getElementById(id);
    action = form.action;
    method = form.method;
    enctype = form.enctype;
    var formData = new FormData(form);
    console.log(formData);
    sendform(formData,action,method,enctype);
   
    return false;
   
}
   
function validatepassword(){
    document.getElementById("test").innerHTML = document.getElementById("cpassword").value;
    if(document.getElementById("password").value===document.getElementById("cpassword").value){
        document.getElementById("validatepassword").style.display = "none";
        document.getElementById("password").style.border = "none";
        document.getElementById("cpassword").style.border = "none";
    }else if(document.getElementById("cpassword").value===""){
       
    }
    else{
        document.getElementById("validatepassword").style.display = "initial";
        document.getElementById("password").style.border = "2px solid red";
        document.getElementById("cpassword").style.border = "2px solid red";
    }
}
</script>
<script type="text/javascript" src="countries.js"></script>
<div id="test"></div>
<form method="post" enctype="multipart/form-data" action="cookie.php" id="login" onsubmit="return setcookie(this.id)">
    Username:<input id="username" type="text" name="username" /><br/>
    Password:<input id="password" onblur="validatepassword()" type="password" name="password" /><br/>
    Confirm Password:<input id="cpassword" onblur="validatepassword()" type="password" name="cpassword" /><br/>
    <label id="validatepassword" style="display:none">The passwords don't match</label><br/>
    Select Country:   <select onchange="print_state('state',this.selectedIndex);" id="country" name ="country"></select><br/>
    City/District/State: <select name ="state" id ="state"></select><br/>
    <input type="file" name="test"/><br/>
    <textarea name="comments" ></textarea>
    <button type="submit" >Submit</button>
</form>
<script language="javascript">print_country("country");</script>

Okay I found the answer here http://stackoverflow...ipart-form-data I needed to remove all headers because they are sent automatically by my form.


Edited by fiveworlds, 23 December 2016 - 09:13 PM.

  • 0




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users