Send POST request to REST API via javascript - javascript

First, I read somewhere that we should not use XMLHttpRequest.
Second, I am a newbie in Javascript.
Third, I created a webpage to submit email and password.
<form method="POST" onsubmit="return check();">{% csrf_token %}
<p><b>Login</b></p>
<input type="email" name="email" placeholder="Email" required></input>
<input type="password" name="password" placeholder="Password" id='new_password' ></input>
<span id='message'>{{msg}}</span>
<button type="submit" onclick="check()" name="Submit"><b>Submit</b></button>
</form>
My check function is
function check() {
document.getElementById('message').innerHTML = "checking";
const url = "https://<hostname/login";
const data = {
'email' : document.getElementById('email').value,
'password' : document.getElementById('password').value
};
const other_params = {
headers : { "content-type" : "application/json; charset=UTF-8" },
body : data,
method : "POST",
mode : "cors"
};
fetch(url, other_params)
.then(function(response) {
if (response.ok) {
return response.json();
} else {
throw new Error("Could not reach the API: " + response.statusText);
}
}).then(function(data) {
document.getElementById("message").innerHTML = data.encoded;
}).catch(function(error) {
document.getElementById("message").innerHTML = error.message;
});
return true;
}
This code is not working and just redirects me to the same page again and again.
Please help me understand what am I doing wrong.

The problem with your code is that you are not "intercepting" the submit event of your form so it will execute the default behavior which is POST to itself (since it doesn't have an instruction that tells it where to go). Unless you can have a chance to stop this default behavior, the form will perform this action.
To intercept the form's submit event you have to tell the browser to watch out of this event and execute a custom function instead of using an event listener like below:
<script>
document.getElementById('whatever-form-id')
.addEventListener('submit', check);
function check(e) {
e.preventDefault();
// and now anything else you want to do.
}
</script>
This will prevent your form from posting and it will execute your function instead.

There were some errors in your code as I've checked, please use it like this
<form method="POST" onsubmit="return check();">{% csrf_token %}
<p><b>Login</b></p>
<input type="email" id = "email" name="email" placeholder="Email" required>
<input type="password" name="password" placeholder="Password" id='new_password' >
<span id='message'>{{msg}}</span>
<button type="submit" onclick="check(event)" name="Submit"><b>Submit</b> </button>
</form>
<script>
function check(event) {
event.preventDefault();
document.getElementById('message').innerHTML = "checking";
const url = "https://hostname/login";
const data = {"email" : document.getElementById('email').value,
'password' : document.getElementById('new_password').value
};
const other_params = {
headers : { "content-type" : "application/json; charset=UTF-8"},
body : data,
method : "POST",
mode : "cors"
};
fetch(url, other_params)
.then(function(response) {
if (response.ok) {
return response.json();
} else {
throw new Error("Could not reach the API: " + response.statusText);
}
}).then(function(data) {
document.getElementById("message").innerHTML = data.encoded;
}).catch(function(error) {
document.getElementById("message").innerHTML = error.message;
});
return true;
}
</script>
Then test by changing your post URL to correct one whether working or not, for more testing use browser inspector tool to see your ajax request.
I've also put it on fiddle for your live testing http://jsfiddle.net/rajender07/xpvt214o/903616/
Thanks

1) Your validation function always returns true
2) When you use fetch..then, its promises can be executed later than return statement
So your form will be refresh again and again. You should return false, and manually submit the form with JavaScript when you get an onSuccess response.
<script>
function check(event) {
document.getElementById('message').innerHTML = "checking";
const url = "https://localhost:8080/login";
const data = {
'email' : document.getElementById('email').value,
'password' : document.getElementById('new_password').value
};
const other_params = {
headers : { "content-type" : "application/json; charset=UTF-8" },
body : data,
method : "POST",
mode : "cors"
};
fetch(url, other_params)
.then(function(response) {
if (response.ok) {
alert(response.json());
} else {
throw new Error("Could not reach the API: " + response.statusText);
}
}).then(function(data) {
document.getElementById("message").innerHTML = data.encoded;
}).catch(function(error) {
document.getElementById("message").innerHTML = error.message;
});
return false;
}
</script>
<form method="POST" onsubmit="return check();">{% csrf_token %}
<p><b>Login</b></p>
<input type="email" id = "email" name="email" placeholder="Email" required></input>
<input type="password" name="password" placeholder="Password" id='new_password' ></input>
<span id='message'>{{msg}}</span>
<button type="submit" name="Submit"><b>Submit</b></button>
</form>
Update:
Page not refreshed, error message displayed:

Firstly, I would like to understand what is your object after getting the data from REST API.
Secondly, there are mistakes in the html code as well, you don't need to add onclick on the submit button when there you already have a onsubmit on the form element.
Solution,
change
onsubmit="check(event);"
function check(e) { e.preventDefault() ... } // you can remove the return true

just going off the top of my head here but you've set the Content-Type to application/json in the headers but your body is not an JSON string
try making your body match the headers by doing
const other_params = {
headers : { "content-type" : "application/json; charset=UTF-8"},
body : JSON.stringify(data),
method : "POST",
mode : "cors"
};
EDIT
So after re-reading your question, I think what is happening is you've set your button to type of submit and what is happening is when you click on the button, your form is getting posted through the good old form post and your page gets refreshed from the postback.
If you want to handle form posts yourself using fetch, change your button type to button and the form should no longer actually post then everything else will be handled by your click event handler.
ps. while you're at it, you can remove the method and onsubmit attribute from your form tag as well
So your form should look something like this
<form>
<p><b>Login</b></p>
<input type="email" name="email" placeholder="Email" required></input>
<input type="password" name="password" placeholder="Password" id='new_password' ></input>
<span id='message'>{{msg}}</span>
<button type="button" onclick="check()" name="Submit"><b>Submit</b></button>
</form>

Related

JS does not detect form submission

$(document).ready(function() {
$("#loginForm").on('submit', function() {
var mail = document.getElementById("mail").value;
var password = document.getElementById("password").value;
req = $.ajax({
url: '/api/login',
type: 'POST',
data: {
email: email,
password: password
}
});
req.done(function(data) {
if (data.result == "failed") {
let messageHandler = document.getElementById("message-handler");
messageHandler.innerHTML = `<h3> username or password incorrect </h3>`;
}
});
return false;
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form action="" method="POST">
<input type="mail" id="mail" name="mail">
<input type="text" id="password" name="password">
<input type="submit" id="loginForm">
</form>
<div id="message-handler">
</div>
When I click the button, it simply says Method not allowed because I am sending a post request from form. The js never detects the on submit event.
Thanks
What happens here in /api/login? Try to point a file like form.php or something else.
req = $.ajax({
**url: '/api/login',**
type: 'POST',
data: {
email: email,
password: password
}
});
Maybe this is the path you need to follow for your answer ;)
Use action='url' Or action='#' this will help to detect your request in browser.

AJAX form - post result data to correct DIV

Can someone help a JS newbie?
Almost everything is working, results are returned, nothing opens new tabs, forms submit to MC database....however I cannot get the result html to post to the correct DIV. All results are being posted to the footer div.
I am guessing my selectors are not specific enough? But I do not have the knowledge on how to structure correctly.
2 forms on page using AJAX submit.
1 pop up form and 1 form in footer..... but all the result html is posting the the div in the footer.
I have adjusted the function register names as suggested (and updated the code below), but form result data is still going to the footer div
//JAVASCRIPT
// FOOTER FORM. waits for form to appear rather than appending straight to the form. Also helps if you have more than one type of form that you want to use this action on.
$(document).on('submit', '#footer-mc-embedded-subscribe-form', function(event) {
try {
//define argument as the current form especially if you have more than one
var $registerFooterFormbutton= jQuery(this);
// stop open of new tab
event.preventDefault();
// submit form via ajax
register($registerFooterFormbutton);
} catch(error){}
});
// POP UP FORM. waits for form to appear rather than appending straight to the form. Also helps if you have more than one type of form that you want to use this action on.
$(document).on('submit', '#pop-mc-embedded-subscribe-form', function(event) {
try {
//define argument as the current form especially if you have more than one
var $registerPopUpFormbutton= jQuery(this);
// stop open of new tab
event.preventDefault();
// submit form via ajax
register($registerPopUpFormbutton);
} catch(error){}
});
// POP UP FORM. post result to div
function register($registerPopUpForm) {
$('#pop-mc-embedded-subscribe-form').val('Sending...');
$.ajax({
type: 'GET',
url: 'https://websitename.us16.list-manage.com/subscribe/post-json?u=.....&c=?',
data: $registerPopUpForm.serialize(),
cache: false,
dataType: 'jsonp',
contentType: 'application/json; charset=utf-8',
error: function (err) { alert('Could not connect to the registration server. Please try again later.') },
success: function (data) {
$('#pop-mc-embedded-subscribe-form').val('pop-subscribe')
if (data.result === 'success') {
// Yeahhhh Success
console.log(data.msg)
$('#pop-mce-EMAIL').css('borderColor', '#ffffff')
$('#pop-subscribe-result').css('color', 'rgb(53, 114, 210)')
$("#pop-subscribe-result").html(data['msg']);
$('#pop-mce-EMAIL').val('')
} else {
// Something went wrong, do something to notify the user.
console.log(data.msg)
$('#pop-mce-EMAIL').css('borderColor', '#ff8282')
$('#pop-subscribe-result').css('color', '#ff8282')
$("#pop-subscribe-result").html(data['msg']);
}
}
})
};
// FOOTER FORM. post result to div
function register($registerFooterForm) {
$('#footer-mc-embedded-subscribe-form').val('Sending...');
$.ajax({
type: 'GET',
url: 'https://websitename.us16.list-manage.com/subscribe/post-json?u=.....&c=?',
data: $registerFooterForm.serialize(),
cache: false,
dataType: 'jsonp',
contentType: 'application/json; charset=utf-8',
error: function (err) { alert('Could not connect to the registration server. Please try again later.') },
success: function (data) {
$('#footer-mc-embedded-subscribe-form').val('footer.subscribe')
if (data.result === 'success') {
// Yeahhhh Success
console.log(data.msg)
$('#footer-mce-EMAIL').css('borderColor', '#ffffff')
$('#footer-subscribe-result').css('color', 'rgb(53, 114, 210)')
$("#footer-subscribe-result").html(data['msg']);
$('#footer-mce-EMAIL').val('')
} else {
// Something went wrong, do something to notify the user.
console.log(data.msg)
$('#footer-mce-EMAIL').css('borderColor', '#ff8282')
$('#footer-subscribe-result').css('color', '#ff8282')
$("#footer-subscribe-result").html(data['msg']);
}
}
})
};
<!--HTML POP UP FORM-->
<form
action="mailchimp url"
method="post"
name="pop-form"
id="pop-mc-embedded-subscribe-form"
class=""
target="_blank"
novalidate
>
<div class="form-group">
<input
type="email"
name="EMAIL"
class="form-control required"
placeholder="Enter your e-mail"
id="pop-mce-EMAIL"
/>
<input
type="submit"
value="SUBSCRIBE HERE"
name="pop-subscribe"
id="pop-mc-embedded-subscribe"
class="button"
/>
</div>
<div id="pop-subscribe-result"></div>
</form>
<!--FOOTER FORM HTML-->
<form
action="mailchimp url"
method="post"
id="footer-mc-embedded-subscribe-form"
name="footer-form"
class=""
target="_blank"
novalidate
>
<div class="mc-field-group">
<label for="mce-EMAIL"
>Email Address <span class="asterisk">*</span>
</label>
<input
type="email"
value=""
name="EMAIL"
class="form-control required email"
id="footer-mce-EMAIL"
placeholder="Email Address *"
/>
</div>
<div class="mc-field-group">
<label for="mce-FNAME">First Name </label>
<input
type="text"
value=""
name="FNAME"
class="form-control"
id="mce-FNAME"
placeholder="First Name"
/>
</div>
<div class="mc-field-group">
<label for="mce-LNAME">Last Name </label>
<input
type="text"
value=""
name="LNAME"
class="form-control"
id="mce-LNAME"
placeholder="Last Name"
/>
</div>
<!-- real people should not fill this in and expect good things - do not remove this or risk form bot signups-->
<div style="position: absolute; left: -5000px;" aria-hidden="true">
<input
type="text"
name="b_dc51fb25cd808abedc98e3ff2_ea4d259202"
tabindex="-1"
value=""
/>
</div>
<div class="footer-btn">
<input
type="submit"
value="Subscribe"
name="footer-subscribe"
id="mc-embedded-subscribe"
class="button"
/>
</div>
<div id="footer-subscribe-result"></div>
</form>
You have two functions with the same name "register" so when you press the submit button in either forms it runs in the register function in the footer since it has the same name as the one dedicated to the popup form
Use this code and your form will work as expected:
//JAVASCRIPT
// FOOTER FORM. waits for form to appear rather than appending straight to the form. Also helps if you have more than one type of form that you want to use this action on.
$(document).on('submit', '#footer-mc-embedded-subscribe-form', function(event) {
try {
//define argument as the current form especially if you have more than one
var $registerFooterFormbutton= jQuery(this);
// stop open of new tab
event.preventDefault();
// submit form via ajax
register1($registerFooterFormbutton);
} catch(error){}
});
// POP UP FORM. waits for form to appear rather than appending straight to the form. Also helps if you have more than one type of form that you want to use this action on.
$(document).on('submit', '#pop-mc-embedded-subscribe-form', function(event) {
try {
//define argument as the current form especially if you have more than one
var $registerPopUpFormbutton= jQuery(this);
// stop open of new tab
event.preventDefault();
// submit form via ajax
register($registerPopUpFormbutton);
} catch(error){}
});
// POP UP FORM. post result to div
function register($registerPopUpForm) {
$('#pop-mc-embedded-subscribe-form').val('Sending...');
$.ajax({
type: 'GET',
url: 'https://websitename.us16.list-manage.com/subscribe/post-json?u=.....&c=?',
data: $registerPopUpForm.serialize(),
cache: false,
dataType: 'jsonp',
contentType: 'application/json; charset=utf-8',
error: function (err) { alert('Could not connect to the registration server. Please try again later.') },
success: function (data) {
$('#pop-mc-embedded-subscribe-form').val('pop-subscribe')
if (data.result === 'success') {
// Yeahhhh Success
console.log(data.msg)
$('#pop-mce-EMAIL').css('borderColor', '#ffffff')
$('#pop-subscribe-result').css('color', 'rgb(53, 114, 210)')
$("#pop-subscribe-result").html(data['msg']);
$('#pop-mce-EMAIL').val('')
} else {
// Something went wrong, do something to notify the user.
console.log(data.msg)
$('#pop-mce-EMAIL').css('borderColor', '#ff8282')
$('#pop-subscribe-result').css('color', '#ff8282')
$("#pop-subscribe-result").html(data['msg']);
}
}
})
};
// FOOTER FORM. post result to div
function register1($registerFooterForm) {
$('#footer-mc-embedded-subscribe-form').val('Sending...');
$.ajax({
type: 'GET',
url: 'https://websitename.us16.list-manage.com/subscribe/post-json?u=.....&c=?',
data: $registerFooterForm.serialize(),
cache: false,
dataType: 'jsonp',
contentType: 'application/json; charset=utf-8',
error: function (err) { alert('Could not connect to the registration server. Please try again later.') },
success: function (data) {
$('#footer-mc-embedded-subscribe-form').val('footer.subscribe')
if (data.result === 'success') {
// Yeahhhh Success
console.log(data.msg)
$('#footer-mce-EMAIL').css('borderColor', '#ffffff')
$('#footer-subscribe-result').css('color', 'rgb(53, 114, 210)')
$("#footer-subscribe-result").html(data['msg']);
$('#footer-mce-EMAIL').val('')
} else {
// Something went wrong, do something to notify the user.
console.log(data.msg)
$('#footer-mce-EMAIL').css('borderColor', '#ff8282')
$('#footer-subscribe-result').css('color', '#ff8282')
$("#footer-subscribe-result").html(data['msg']);
}
}
})
};
You are defining the register() function two times with the same name. The second one overwrites the first and everytime you call the function with that name you call the second function. An easy solution is to change the name of the functions (i.e registerPopUpForm() , registerFooterForm() ) and use them accordingly.

Why Ajax is sending object in Response?

I have a very simple script in php that is supose to send a request to ajax and return the string im putting in the .php file but when the request respond, it sends an object instead of the string. I dont know why this is hapening because i already have done this the same way previusly and works fine.
this is the form that send the request
<form method="POST" id="personForm">
<div class="form-group col-md-6">
<label for="NameInput">Name</label>
<input type="text" name="name" class="form-control" id="NameInput">
</div>
<div class="form-group col-md-6">
<label for="lNameInput">Last Name</label>
<input type="text" name="lastname" class="form-control" id="lNameInput">
</div>
<input type="button" name="Send" class="btn btn-info" onclick="ajaxRequest($('#NameInput').val(), $('#lNameInput').val())" value="Send">
</form>
<hr>
<div id="result">
</div>
This is the script that send the ajax request
function ajaxRequest(name, lastn) {
var params = {
"name" : name,
"lastn" : lastn
};
$.ajax({
url: './process/resquestAjax.php',
method: 'POST',
data: params,
beforeSend: function() {
$('#result').html('<p>Procesando Peticion...</p>');
},
complete: function(completeResult) {
$('#result').html(completeResult);
},
sucess: function(successResult) {
},
error: function(jqXHR,estado,error){
alert('There was an error!: '+estado+' name-> '+error+' otro-> '+jqXHR);
alert("Please contact support ias soon as posible...!");
}
}); // End Ajax Call
}
and the php file is just this
$nombre = $_POST['name'];
$apellido = $_POST['lastname'];
echo "¡Hello! your name is : ". $nombre ." and your last name: ". $apellido;
I dont know why im not getting the string of that echo in the response of the ajax. it sends an object instead. I'm trying to make other project with database with this but i have the same issue.
See the documentation. You're using the complete callback, which receives the jqXHR object as its first argument.
Instead, you want to use the success (two cs, note), not complete, if you want to use the returned data. success receives the data as its first argument. (You can also use complete to remove the in-progress message, etc.)
So for instance:
function ajaxRequest(name, lastn) {
var params = {
"name" : name,
"lastn" : lastn
};
$.ajax({
url: './process/resquestAjax.php',
method: 'POST',
data: params,
beforeSend: function() {
$('#result').html('<p>Procesando Peticion...</p>');
},
complete: function(completeResult) {
// If you wanted to do something whether the request
// succeeded or failed, you'd do it here. Otherwise,
// remove this handler.
},
success: function(successResult) {
$('#result').html(successResult);
},
error: function(jqXHR,estado,error){
alert('There was an error!: '+estado+' name-> '+error+' otro-> '+jqXHR);
alert("Please contact support ias soon as posible...!");
}
}); // End Ajax Call
}

Laravel csrf token mismatch on ajax post a second time

im trying to submit an ajax post in laravel but im having some problem regarding the form's csrf token. In my form, if the conditions i set in my ajax post url has been met the first time the form has been submitted. However if i submit the form and purposely failed the conditions i set in my ajax post url in the first try, If i submit the form again i get a token mismatch exception in my ajax error log. Do i need to refresh the csrf_token every ajax post?
Below is my code
JS
$(document).on('submit','.registration-form',function(e){
e.preventDefault();
var form = $(this);
var form_url = $(this).attr("action");
var form_values = $(this).serialize();
$.ajax({
url:form_url,
type:'POST',
data:form_values,
dataType: 'json',
async:false,
success: function(result){
console.log(result);
if(result['status']==true){
location.href = result['redirect'];
}
else{
form.find(".form-details").show().html(result['message']);
}
},
error: function(ts) {
console.log(ts.responseText)
}
});
});
HTML
<form action="{{ url('login') }}" method="POST" class="registration-form">
{{ csrf_field() }}
<input type="text" name="username" class="input" placeholder="Email">
<input type="password" name="password" class="input" placeholder="Password">
<button class="button is-redbox is-flat is-fullwidth">Login</button>
</form>
Are u sure that each time that is send in ajax?
data: {
"_token": "{{ csrf_token() }}",
}
$("#cform")[0].reset();
or in plain javascript:
document.getElementById("cform").reset();
public function regenerateToken(){
session()->regenerate();
return response()->json([
'msg'=>'success',
'token'=>csrf_token()
]);
}
$('#form').submit(funtion(event) {
event.preventDefault(event);
// Submit the form using AJAX.
$.ajax({
type: 'POST',
url: form.attr('action'),
data: formData
})
.done(function(response) {
// Make sure that the formMessages div has the 'success' class.
if (response.msg === 'success') {
$('#token').val(response.token);
console.log($('#token').val());
}
}
$('input[type="text"],input[type="email"] ,textarea, select').val(''); $(this).trigger('reset');
});

C# WebApplication POST

I'm trying to POST a form using C#
I make some searches, however I couldn't code it right way (I am new in this field).
Here are my codes;
View;
<form>
<div class="field-wrap">
<label>
Email Address<span class="req">*</span>
</label>
<input type="email" id="input-username" name="Username" required autocomplete="on" />
</div>
<div class="field-wrap">
<label>
Password<span class="req">*</span>
</label>
<input type="password" id="input-password" name="Password" required autocomplete="on"/>
</div>
<p class="forgot">Forgot Password?</p>
<button class="button button-block" id="button-login">Log In</button>
</form>
Controller;
// GET: User
[HttpPost]
public ActionResult Login()
{
string username = Session["Username"].ToString();
string password = Session["Password"].ToString();
Service iLocationService = new Service();
var result = Service.MemberGetLogin( username, password, "127.0.0.1" );
ViewBag.Message = result;
return View();
}
Javascript;
jQuery(document).ready(function () {
$("#button-login").click(function () {
$.ajax({
type: "POST",
url: "/Controllers/UserController/login/",
data: $(this).serialize(),
dataType: "json"
})
.done(function (result) {
console.log(result);
})
.fail(function (a) {
console.log( a);
});
});
});
What I am trying to do is POST the input values to chech the user.
Thanks in Advance
Look at this line
string username = Session["Username"].ToString();
In your code you are trying to read the username and password values from Session variables. Who set the user name and password to Session ? You should be reading those from the posted form and use that.
[HttpPost]
public ActionResult Login(string userName,string password)
{
// do something with userName and password and return something
}
Also, you need to make sure that you are serializing the form, not the button clicked. I personally prefer to use the Html helper method to generate the form tag and use the action attribute value of the form in my javascript code instead of hardcoding the urls.
So in my razor view
#using(Html.BeginForm("login","User"))
{
//Your existing form inputs goes here
<button class="button button-block" id="button-login">Log In</button>
}
and in the script
$("#button-login").click(function () {
$.ajax({
type: "POST",
url: $(this).closest("form").attr("action"),
data: $(this).closest("form").serialize()
})
});
Since you are doing an ajax form submit, i suggest you return a json response which your client code can parse and do further things.
[HttpPost]
public ActionResult Login(string userName,string password)
{
//if userName and password are valid
return Json(new { Status="success"});
// else
return Json(new { Status="failed", Message="Invalid credentials});
}
and in your done callback, you should inspect this value and do further things
.done(function (result) {
if(result.Status==="success")
{
window.location.href="/Home/Index"; // change to wherever you want to redirect to
}
else
{
alert(result.Message);
}
})

Categories