how to use an API on web, using Ajax and Javascript? - javascript

I want to implement a login by calling an API using Ajax and Javascript.
User enters username and password and by clicking a button "login()" would be called. If input is correct it should open the welcome page. I implemented it as below. But it does not work!
function login() {
var url = "http://...";
var username = document.getElementById("username").value;
var password = document.getElementById("password").value;
var xhr = new XMLHttpRequest();
xhr.open("POST", url, true);
xhr.setRequestHeader("Content-Type", "application/json");
console.log("before function. ")
xhr.onreadystatechange = function () {
console.log("before if. ")
if (this.readyState == 4 && this.status == 200) {
console.log("inside if. " + xhr.responseText);
window.open(welcome);
}
};
var obj = { UserName: username , Password: password }
var data = JSON.stringify(obj);
xhr.send(data);
console.log("END ");
}
As suggested, I added several console log to debug it and I found out that it never run inside the if. There is no error on console and here's the output on console:
before function.
END
before if.
(before was repeated 3 times)
I have already checked API by Postman. It works.
If username and password are correct, it returns all information of user and the http status code is 201. If input is incorrect then it returns an error message and status code is 401.

Related

Read response from HttpRequest in JavaScript

First, you can ignore that this is sending credentials in an unsafe manner. I'm supposed to handle that after.
My problem is with reading the 'response' or 'responseText' from a HttpRequest to an API. I can see in the console the request is succesful and the response I want is there, but I am not able to retrieve it. I must be missing something basic probably.
This is the response as I can see in the console:
Chrome console
I can see the "web.html" that I want to retrieve and also the status 200. But the console log is empty. This is how I am trying to do this.
const request = new XMLHttpRequest();
request.open('POST', 'https://someurl.net/api/user/login');
const form = document.getElementById('login')
form.addEventListener('submit', callbackFunction);
function callbackFunction(event) {
event.preventDefault();
request.setRequestHeader('Content-Type', 'application/json;charset=UTF-8')
request.send(JSON.stringify(formJson(event)));
console.log(request)
console.log("Status: " + request.status);
console.log("Response: " + request.response);
console.log("ResponseText: " + request.responseText);
};
function formJson(event) {
const credentialsDto = {};
const myFormData = new FormData(event.target);
console.log(myFormData);
myFormData.forEach((value, key) => (credentialsDto[key] = value));
return credentialsDto;
}
For some more details, this is calling my Api in .NET which returns 401 Unauthorized if the credentials are wrong, and 200 OK with a string as in Ok("web.html") if the credentials are correct.
Thank you.
I tried printing the request and trying with all its attributes I could think of. I can see the request is working and the server is sending the response I want, but I am clueless as how to retrieve it properly.
I also tried this thinking that the response might be asynchronous but it didn't work:
while (true)
{
if (request.readyState == 1)
{
console.log("Status: " + request.status);
console.log("Response: " + request.response);
console.log("ResponseText: " + request.responseText);
break;
}
}
The console is empty because the readyState property state 1 merely means that the connection with the server is established.
Furthermore, the XMLHttpRequest object you print to the console is updated immediately when the http-response file is received, which gives the false assumption that it can't be accessed.
This is more or less a boilerplate code-snippet for waiting for the http-response
const request = new XMLHttpRequest();
request.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("demo").innerHTML =
this.responseText;
}
};
Now let's tailor it with the code you submitted:
const request = new XMLHttpRequest();
const form = document.getElementById('login')
form.addEventListener('submit', callbackFunction);
function callbackFunction(e) {
event.preventDefault();
request.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
console.log("Status: " + request.status);
console.log("Response: " + request.response);
console.log("ResponseText: " + request.responseText);
}
};
request.open('POST', 'https://someurl.net/api/user/login');
request.setRequestHeader('Content-Type', 'application/json;charset=UTF-8')
request.send(JSON.stringify(formJson(e)));
console.log(request)
};
function formJson(e) {
const credentialsDto = {};
const myFormData = new FormData(e.target);
console.log(myFormData);
myFormData.forEach((value, key) => (credentialsDto[key] = value));
return credentialsDto;
}
This should do it. Notice that event is deprecated and that you would continue using e instead.
Instead of depending on the onreadystatechange property, you could also choose for:
request.onload = function(e) {/*Your code*/};
An eventlistener which automatically looks for the succes denoting parameters and is a hack of a lot shorter.
I hope this helps.

How to send an ajax request on form submit without affecting the actual form

I want to create a signup form that will validate your input and then send an AJAX request to a PHP page to check if your username has already been used. After that it will submit the actual form (the location is in an action attribute).
function validate() {
if (fullname.length < 90) { /*this is validating the form*/
var username_input = document.forms["myform"]["username"].value;
if (window.XMLHttpRequest) {
var usernamecheck = new XMLHttpRequest();
} else if (window.ActiveXObject) {
var usernamecheck = new ActiveXObject("Microsoft.XMLHTTP");
}
usernamecheck.open("POST", "reciever.php", true);
usernamecheck.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
usernamecheck.send("user=" + username_input); /*sending username to check if it exists*/
usernamecheck.onreadystatechange = function() {
if (usernamecheck.readyState == 4 && this.status == 200) {
if (usernamecheck.responseText == "user") {
alert('username has already been used');
return false;
}
}
};
var contactcheck = new XMLHttpRequest(); /*second request*/
contactcheck.open("POST", "reciever.php", true);
contactcheck.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
contactcheck.send("contact=" + contactw);
contactcheck.onreadystatechange = function() {
if (contactcheck.readyState == 4 && this.status == 200) {
if (contactcheck.responseText == "contact") {
alert('email has already been used');
return false;
}
}
};
}
/*reference 1 (see below)*/
}
My problem is that the form submits even before the AJAX runs, and if I add return false; where the script says ‘reference 1’ the AJAX runs, but the form does not submit.
Your question is similar to this one:
check if username exists in real-time through AJAX in php with mysql
Quoting the post:
"Send your data in javascript using jQuery like this:"
$.post( "check.php", { user: $("#username").val() }, function (data){
if(data=='1'){
//do 1
}
elseif(data=='0'){
//do 0
}
});
In your check.php get username like this
//some basic validation
if(!isset($_POST['user'] || empty($_POST['user']))
{
echo '0'; exit();
}
$username = trim($_POST['user']);
"For this to work properly you check.php must return either 1 or 0, do not echo mysql errors there or whatsoever. if any error occur, just echo 0."
If your function is used as an event handler, like addEventListener('submit', validate) or onsubmit="validate()" then you should check the Event object send with the submit event and prevent the default submit behavior of the form.
You can do that with the event.preventDefault() method which, like it says, prevents the default behavior of the form, which is submitting.
But the reason why your return false statements are not working, are because of the asynchronous nature of XMLHttpRequest.send(). This means that the function will not wait for the return statement because it is inside a function that is called way later. The reason for his behavior is to let other code run while you wait for a response for the server instead of holding up the code until the request has finished.
You also can send multiple values to the server in a single request instead of doing two separate requests. AJAX requests should be optimized as much as possible as they (can be) taxing on both the client and server.
See the snippets below to see how you could do all the above.
function validate(event) {
if (fullname.length >= 90) {
return; // Stop function if condition is not met.
}
event.preventDefault(); // Prevent form from submitting.
var form = event.target; // The target is the form that is submitting.
var userName = form.elements['username'].value;
var email = form.elements['email'].value; // I assume this was missing.
var request;
if (window.XMLHttpRequest) {
request = new XMLHttpRequest();
} else if (window.ActiveXObject) {
request = new ActiveXObject("Microsoft.XMLHTTP");
}
request.open("POST", "reciever.php", true);
request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
request.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var response = this.responseText;
if (response === "user") {
alert('Username has already been used');
} else if (response === "email") {
alert('Email has already been used');
}
}
};
request.send('user=' + userName + '&email=' + email); // Send both user name and email values.
}
It seems that you use legacy code like ActiveXObject which is not used anymore by current browsers. If you really need it for older browsers, then you're good. If you care for a more modern approach and don't need to support old browsers then look at the example below. It (almost) does the same thing, but with a different syntax.
const alerts = {
'user': 'Username has already been used',
'email': 'Email has already been used'
};
async function validate(event) {
if (fullname.length >= 90) return;
event.preventDefault();
const formData = new FormData(event.target);
try {
const response = await fetch('reciever.php', {
method: 'POST',
body: formData
}
if (!response.ok) {
throw new Error(`
Check has failed. -
${response.status}:
${response.statusText}`
);
}
const text = await response.text();
if (text in alerts) alert(alerts[text]);
} catch (error) {
console.error(error);
}
}

Return WebMethod Response & Use If Statement To Alert User Based On Response

I'm trying to include an if statement that analyzes the webmethod response which is either true or false. I just want to alert the user the post was successful if the response is true or the post was not successful if the response is false.
I can get the response using xhttp.responseText but I can't figure out how to build that into an if statement inside my javascript below:
//JavaScript that Posts to WebMethod
<script>
function createNewComment() {
var xhttp = new XMLHttpRequest();
var url = "http://localhost:57766/PALWebService.asmx/insertComment"
var a = document.getElementsByName("existingguid")[0].value;
var b = document.getElementsByName("newcomment")[0].value;
var c = 'existingguid=' + a + '&newcomment=' + b;
xhttp.open("POST", url, true);
xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
}
};
xhttp.send(c);
}
</script>
I figured it out. After checking that readyState was 4 and status was 200 I simply nested another if statement to check the responseText from the XMLHttpRequest and it was true I called another function and if it was false I notified user the post failed on the webmethod. It may not be perfect, but it works for what I need.
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
if (xhttp.responseText = true) {
addComment(b, today, userName);
}
else {
document.getElementsByName("newcomment")[0].value = '';
$("#commentLabel").html("Your comment was not saved in the database. Please try again or contact system admin.");
}
}
};

How to GET a response with a given URL and a username and password?

I have been asked to load drop down boxes from an OLAP server and the server credentials are given. They are as follows
url
HTTP Method - POST
auth user: abc123
auth pwd: api123
REQ/RES content type/charset = application/json; charset=UTF-8
The following is the code I have written:
var hr = new XMLHttpRequest();
var url= "http://someIPAddress/getData";
alert("Before Posting data");
hr.open("POST",url,true);
alert("Connection open");
document.getElementById("submitButton").disabled = true;
document.getElementById("status").innerHTML = "Loading...";
hr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
hr.onreadystatechange = function(){
alert("Entered callback function...");
if(hr.readyState == 4 && hr.status == 200){
var return_data = hr.responseText;
alert(return_data);
}
else{
alert("There is a connection issue");
var return_data = hr.responseText;
}
}
ajaxReq.send("POST",url,function populate(){
alert("Request received");
})
}
These are the exact data provided (except the url, username and password. Am not disclosing it here the actual data)
I am trying to use the XMLHttpRequest() by specifying the URL, POST and the call back function. How to pass the username and password here so that it responds you with data
When I try to access the url, it asked me for User name: and Password:
I dont know how to append the credentials with the url, as I am not specified the exact key to the values. Could you please help. I think I am missing out on something
You need to send an Authorization header with the request. This header value consists in the username followed by a ':' and the password, encoded as base64:
hr.setRequestHeader('Authorization', 'Basic ' + btoa(username + ':' + password));
btoa() encodes a string as base64.
Have you tried an URI like http://user:pass#someIPAddress/getData perhaps this will be all you need. I had never tried it submitting a form but you can check

AJAX POST returning null values

I have tried and tested various methods for completing this task for about a day now. Please be forewarned that I am building this simply, and then working my way up!
I have a form that consists of a textarea, and two input fields. The input fields allow a XMLHttpRequest to send information pertaining to a username, and message - sent to a chatroom that I am trying to make.
The problem that I have with my request, is simply that I can send the information, and insert a row into a database, but I can't get any information back! You will see from the code below, that I have put an alert in, to check what the response text is, but it comes back as null (not undefined, but ""). Please check the code below:
function insertMessage() {
var username = document.getElementById('username').value;
var message = document.getElementById('message').value;
var queryString = "username=" + username + "&message=" + message;
// send the username and message information to be inserted into the database
var url = 'classes/chatroom/chatroom.upload.php';
// create xml request
var request = createCORSRequest("POST", url)
// create a function that will receive data sent from the server
request.onreadystatechange = function () {
if (request.readyState == 4 && request.status == 200) {
alert(request.responseText);
}
}
request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
request.send(queryString);
}
function createRequest(method, url) {
var thisRequest = new XMLHttpRequest();
if ("withCredentials" in thisRequest) {
// thisRequest has 'withCredentials' property only if it supports CORS
thisRequest.open(method, url, true);
} else if (typeof XDomainRequest != "undefined") { // if IE use XDR
thisRequest = new XDomainRequest();
thisRequest.open(method, url);
} else {
thisRequest = null;
}
return thisRequest;
}
The code that pertains to the insertion of a database row is:
<?php
include 'chatroom.config.inc.php'; // the database file
$message_username = $_POST['username'];
$message_content = $_POST['message'];
if ($message_username == "Username: Once entered, you don't have to enter again" || $message_username == "") {
$message_username = "Guest";
}
if ($message_content == "Message:" || $message_content == "") {}
else {
$users->post_message($message_username, $message_content); // insert database row using PDO query
}
?>
Could anyone provide a clue as to where I'm going wrong?
The code looks good to me, your PHP code is inserting the data in DB but it isn't returning back any text or value.
For values to be retrieved on the client side i.e. on successful completion of your ajax request, you will have to send the data to client side.
Try using php's echo function and return the text / value.

Categories