Jump to content

Javascript XHR SPA forms.


fiveworlds

Recommended Posts

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"];
?>​
Link to comment
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
Link to comment
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.

Link to comment
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
Link to comment
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
Link to comment
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
×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.