Sign in to follow this  
Followers 0
fiveworlds

Javascript XHR SPA forms.

5 posts in this topic

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.com/questions/6211145/upload-file-with-ajax-xmlhttprequest and one response mentioned I should use FormData https://developer.mozilla.org/en-US/docs/Web/API/FormData/FormData and parse it as raw data on the server http://php.net/manual/en/reserved.variables.httprawpostdata.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

Share this post


Link to post
Share on other sites

https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/onreadystatechange

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
0

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites

Try using alert()
http://www.w3schools.com/jsref/met_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
0

Share this post


Link to post
Share on other sites
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.com/questions/12348216/uploading-a-file-with-xmlhttprequest-missing-boundary-in-multipart-form-data I needed to remove all headers because they are sent automatically by my form.

Edited by fiveworlds
0

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0