Sign in to follow this  
fiveworlds

Javascript XHR SPA forms.

Recommended Posts

fiveworlds    67

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"];
?>​

Share this post


Link to post
Share on other sites
Sensei    604

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

Share this post


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

Share this post


Link to post
Share on other sites
Sensei    604

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

Share this post


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

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