I am trying to use Ajax to validate a username and password stored in a php document on a server. The usernames and passwords are pre stored in the document.
On my HTML page is a field for the username, and a field for the password. Then, when they click the Log-In button it calls the following function:
function checkLogin() {
var user = document.getElementById("username").value;
var password = document.getElementById("password").value;
var data = "userName=" + user + "&password=" + password;
var request = new XMLHttpRequest();
request.open("POST", "check.php", false);
request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
request.send(data);
if (request.status === 200) {
window.open("test.html");
} else {
var messageSpan = document.getElementById("response");
var responseJson = JSON.parse(request.responseText);
messageSpan.innerHTML = "Your password of " + responseJson["password"] + " was not corerct. Please try again.";
}
}
The problem I'm having is that it never gets to the else if the username/password are incorrect. Even if there's nothing in the fields, it opens the new page. What am I doing wrong for it to think that all data is correct?
NOTE: The above code is for testing purposes only, and won't actually be used when publishing the web page. I just want to see what's happening and get it to work before moving on. Thanks.
Most likely your check.php echos out true or false on response in some cases you echo out user ID on success. Anyways, your response code is 200 for successful server communication. Examine request.responseText in case of getting 200.
if (request.readyState == 4 && request.status === 200) {
var responseJson = JSON.parse(request.responseText);
if (responseJson['success'] == 1){
window.open("test.html");
} else {
var messageSpan = document.getElementById("response");
messageSpan.innerHTML = "Your username and password combination was incorrect.";
}} else {
//For debugging purpose add an alert message here. alert(request.status);
messageSpan.innerHTML = "A server connection error occurred!"; }
It's noticeable that you are sending back json response. So you may add a node called success whith value of true or false to examine logged in success. It's not a good practice to show password in response message though.
Well the problem is you are getting status 200 from your check.php every time.
In your check.php you need to do some thing like
// let validate() be function that validates your username/password
// and returns true/false on validation
if(validate()){
http_response_code(200);
} else {
http_response_code(401);
}
hope it helps
simply you can use ajax like this,
<script>
function checkLogin() {
var user = document.getElementById("username").value;
var password = document.getElementById("password").value;
$.ajax({
xhr: function() {
var xhr = new window.XMLHttpRequest();
//progress
xhr.upload.addEventListener("progress", function(e) {
//progress value e
}, false);
return xhr;
},
type: "POST",
url: "check.php",
data: {'userName' : user , 'password' : password},
dataType:json,
success: function(msg) {
//when success //200 ok
if(msg.status=="done"){
window.open("test.html");
}else{
var messageSpan = document.getElementById("response");
messageSpan.innerHTML = "Your password of " + msg.password+ " was incorrect.";
}
},
error: function(jqXHR, textStatus, errorThrown) {
//when error
}
});
}
</script>
your php server side like this,
//$status="fail" or "done"
//success must be always success
$respond=array("success"=>"success","status"=>$status,"password"=>$password);
echo json_encode($respond);
exit;
I think this useful for you !
Related
I have a registration form. The PHP is checking for errors such as short password
AJAX gives an alert with the echo error from PHP.
With PHP, after an if else statement,
the user will be registered and redirected successfully to index.php (good)
header('Location:home.php');
exit;
The problem is, if there is any error, the user will be redirected to handler.php and the echo alert shows there (on white page)
var form = document.querySelector('.register form');
form.onsubmit = function(event) {
event.preventDefault();
var form_data = new FormData(form);
var xhr = new XMLHttpRequest();
xhr.open('POST', form.action, true);
xhr.onload = function() {
document.querySelector('.msg').innerHTML = this.responseText;
};
if (xhr.status >= 200 && xhr.status <= 299) {
var response = JSON.parse(xhr.responseText);
if (response.location) {
window.location.href = response.location;
} else {
xhr.send(form_data);
}
}
Example 2: the alerts will display properly at <div class="msg"></div> position
(But will also throw the index.php on registration form, where the alerts go)
var form = document.querySelector('.register form');
form.onsubmit = function(event) {
event.preventDefault();
var form_data = new FormData(form);
var xhr = new XMLHttpRequest();
xhr.open('POST', form.action, true);
xhr.onload = function() {
document.querySelector('.msg').innerHTML = this.responseText;
};
xhr.send(form_data);
};
So, i want the user to be redirected to index.php & also the alerts to be handled by AJAX
Regarding responding to AJAX requests with redirects, please see What is the difference between post api call and form submission with post method?. Does a better job explaining than I could.
The basic idea is that when called asynchronously, your PHP should do what it needs to do and respond with either a 200 (success) or an error status like 400 (bad request) + error details.
// make sure nothing is echo'd or otherwise sent to the
// output buffer at this stage
$errors = []; // collect errors in here
// do whatever you need to do with the $_POST / $_FILES data...
// capturing errors example...
if ($_POST['cpassword'] != $_POST['password']) {
$errors[] = "Passwords do not match!";
}
// use content negotiation to determine response type
if ($_SERVER['HTTP_ACCEPT'] === "application/json") {
if (count($errors)) {
header("Content-type: application/problem+json");
http_response_code(400);
exit(json_encode([
"message" => "Invalid form data or something",
"errors" => $errors
]));
}
header("Content-type: application/json");
exit(json_encode(["location" => "home.php"]));
}
// just a normal request, respond with redirects or HTML
// ...
foreach ($errors as $error) : ?>
<div class="error"><?= $error ?></div>
<?php endforeach;
The client can navigate to home on success or display error information otherwise
document.querySelector(".register form").addEventListener("submit", async (e) => {
e.preventDefault()
const form = e.target
const body = new FormData(form)
// fetch is much easier to use than XHR
const res = await fetch(form.action, {
method: "POST",
headers: {
accept: "application/json", // let PHP know what type of response we want
},
body
})
const data = await res.json()
if (res.ok) {
location.href = data.location
} else if (res.status === 400) {
document.querySelector('.msg').textContent = data.message
// also do something with data.errors maybe
}
})
TLDR: I would like to wait for the 1st request to be done, before continuing to the 2cnd etc.
Hello,
I am currently working on a HotSpot page. The user needs to input his email, and Voila! he gets internet access.
The thing that is SUPPOSED to happen in the background, is that when the user inserts his email and presses send;
an AJAX async POST is made to the router, with username and password,
then the js/html page waits for the readyState === 4 (DONE) response from the router,
an AJAX async POST is made to a server on a different network (which requires the user to have internet connection), which sends the users email,
then the js/html page waits for the DONE response
the user is redirected.
Thats basically what should happen. What is actually happening, is that the JS does not wait for the readyState === 4 and Status === 200. Once the user clicks Submit, he is redirected right away.
I can't use JQuery, as the router (Mikrotik) is using $ for it's own purpose.
After inspecting the network with the F12 tool, I can see that the POST to router has a status of 200, and is carrying the correct Parameters (username=HSuser&password=SimpleUserPassword) and I can see that the POST to the server has a status of 200 and also has the correct Parameters (email address ie: Email=Ba%40loo.ns).
I guess my JS code is somehow wrong, as it does not wait.
Also, for some reson after fiddling with the code, no more emails are inserted into the Database (they were before, don't know what the is problem now.)
Below is the current code. I'll also post a previous version (which also didn't work) in case someone can spot the problem there.
In case anyone requires any additional information, let me know.
Thank you.
Edit 3.:
I continued to read Stack Overflow and I've stumbled onto this piece of information...
The server is responsible for providing the status, while the user agent provides the readyState.
Is this done server side automatically, or do I need to implement it somehow?
Edit 1.:
I tried console log here
if (xhr.readyState === DONE){
console.log("XHR1" + xhr.readyState);
console.log("XHR1" + xhr.status);
if (xhr.status === OK){
and here
if (xhr2.readyState === DONE){
console.log("XHR2" + xhr2.readyState);
console.log("XHR2" + xhr2.status);
if (xhr2.status === OK){
and I only got XHR1 (XHR14 and XHR1200), I didn't get anything from XHR2.
Edit 2.:
Tried replacing onreadystatechange with onload, still does the same thing.
Current HTML code:
<!DOCTYPE html>
<html>
<head>
<meta content="text/html" />
<meta charset="utf-8" />
<title>HotSpot</title>
</head>
<body>
<!-- Email form which is saved into the DB -->
<form accept-charset="utf-8" name="mail" onsubmit="return false;" method="post" id="mail">
<h1>Hotspot</h1>
<h2>To gain internet access, enter your email.</h2>
<br />
<input type="text" id="email" name="email" autofocus="autofocus" />
<br />
<input type="submit" value="Submit" id="submit_ok" name="submit_ok" /> <br />
</form>
<script type="text/javascript">
document.getElementById("submit_ok").addEventListener("click", SendAjax);
function SendAjax() {
var email = document.getElementById("email").value;
console.log(email);
// Check if fields are empty
if (email=="") {
alert("Please enter your email.");
}
// AJAX code to submit form
else{
var xhr = new XMLHttpRequest();
xhr.open('POST', 'http://router/login', true);
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded", "Access-Control-Allow-Origin: *");
xhr.onreadystatechange = function () {
var DONE = 4;
var OK = 200;
if (xhr.readyState === DONE){
if (xhr.status === OK){
var xhr2 = new XMLHttpRequest();
xhr2.open('POST', 'http://server/insertDB.php', true);
xhr2.setRequestHeader("Content-type", "application/x-www-form-urlencoded", "Access-Control-Allow-Origin: *");
var useremail = document.getElementById("email").value;
xhr2.onreadystatechange = function () {
if (xhr2.readyState === DONE){
if (xhr2.status === OK){
location.href = "http://server/redirected.html";
}
}
}
}
xhr2.send("Email="+encodeURIComponent(useremail));
}
}
xhr.send("username=HSuser&password=SimpleUserPassword");
}
};
</script>
</body>
</html>
Current PHP code:
<?php
require ('connect.php');
$clean_email = "";
$cleaner_email = "";
if(isset($_POST['email']) && !empty($_POST['email'])){
//sanitize with filter
$clean_email = filter_var($_POST['email'], FILTER_SANITIZE_EMAIL);
//sanitize with test_input
$cleaner_email = test_input($clean_email);
//validate with filter
if (filter_var($cleaner_email,FILTER_VALIDATE_EMAIL)){
// email is valid and ready for use
echo "Email is valid";
//Email is a column in the DB
$stmt = $DB->prepare("INSERT INTO addresses (Email) VALUES (?)");
$stmt->bind_param("s", $cleaner_email);
$stmt->execute();
$stmt->close();
} else {
// email is invalid and should be rejected
echo "Invalid email, try again";
}
} else {
echo "Please enter an email";
}
function test_input($data) {
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data);
return $data;
}
$DB->close();
?>
Previous HTML/JS code:
function SendAjax() {
var email = document.getElementById("email").value;
console.log(email);
// Check if fields are empty
if (email=="") {
alert("Please enter your email.");
}
// AJAX code to submit form
else{
var xhr = new XMLHttpRequest();
xhr.open('POST', 'http://router/login', true);
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded", "Access-Control-Allow-Origin: *");
xhr.onreadystatechange = function () {
var DONE = this.DONE || 4;
if (xhr.readyState === XMLHttpRequest.DONE){
var xhr2 = new XMLHttpRequest();
xhr2.open('POST', 'http://server/insertDB.php', true);
xhr2.setRequestHeader("Content-type", "application/x-www-form-urlencoded", "Access-Control-Allow-Origin: *");
var useremail = document.getElementById("email").value;
xhr2.onreadystatechange = function () {
var DONE = this.DONE || 4;
if (xhr2.readyState === XMLHttpRequest.DONE) {
location.href = "http://server/redirected.html";
}
};
xhr2.send("Email="+encodeURIComponent(useremail));
}
}
xhr.send("popup=true&username=HSuser&password=SimpleUserPassword");
}
}
If it makes your life easier (and it WILL), you can put jQuery into no conflict mode.
<!-- Putting jQuery into no-conflict mode. -->
<script src="prototype.js"></script>
<script src="jquery.js"></script>
<script>
var $j = jQuery.noConflict();
// $j is now an alias to the jQuery function; creating the new alias is optional.
$j(document).ready(function() {
$j( "div" ).hide();
});
// The $ variable now has the prototype meaning, which is a shortcut for
// document.getElementById(). mainDiv below is a DOM element, not a jQuery object.
window.onload = function() {
var mainDiv = $( "main" );
}
</script>
https://learn.jquery.com/using-jquery-core/avoid-conflicts-other-libraries/
Then you can make your AJAX call, and the stuff that should wait can go in the success function:
$j.ajax({
url: '/your-form-processing-page-url-here',
type: 'POST',
data: yourVariables,
mimeType: 'multipart/form-data',
success: function(data, status, jqXHR){
alert('Hooray! All is well.');
console.log(data);
console.log(status);
console.log(jqXHR);
},
error: function(jqXHR,status,error){
// Hopefully we should never reach here
console.log(jqXHR);
console.log(status);
console.log(error);
}
});
Hello i now using this php code for get steam nicknames
function EchoPlayerName($steamid){
$xml = simplexml_load_file("http://steamcommunity.com/profiles/$steamid/?xml=1");//link to user xml
if(!empty($xml)) {
$username = $xml->steamID;
echo $username;
}
}
or
$steam = file_get_contents("http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?key={API_KEY}&steamids=$steamid64", true);
$steamarray = json_decode($steam, true);
$name = $steamarray['response']['players'][0]['personaname'];
but i this using for listing players and loading page is slow
so i want this data load via javascript after full load page
any ideas?
API example
{"response":{"players":[{"steamid":"76561197964477177","communityvisibilitystate":3,"profilestate":1,"personaname":"The [G]amerX #ππ¨π‘π£πππ¬.π½πΏπΌ","lastlogoff":1558765863,"commentpermission":1,"profileurl":"https://steamcommunity.com/id/gamerxcz/","avatar":"https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/66/6673d6df066386d232164e8f9a5d9b36cad1d013.jpg","avatarmedium":"https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/66/6673d6df066386d232164e8f9a5d9b36cad1d013_medium.jpg","avatarfull":"https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/66/6673d6df066386d232164e8f9a5d9b36cad1d013_full.jpg","personastate":0,"realname":"Community Owner","primaryclanid":"103582791433644720","timecreated":1076786008,"personastateflags":0,"loccountrycode":"CZ"}]}}
First, you should get Data using ajax of pure javascript or jquery. Then you should target an HTML element that you want to fill it using this retrieved data. Imagine element with ID target.
jQuery:
$(document).ready(function () {
$.ajax({
url: "http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?key={API_KEY}&steamids=$steamid64",
}).done(function (data) {
var json = JSON.parse(data);
$('#target').text(json['response']['players'][0]['personaname']);
});
});
pure javascript:
var xhr = new XMLHttpRequest();
xhr.open('POST', 'http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?key={API_KEY}&steamids=$steamid64');
xhr.onload = function () {
if (xhr.status === 200) {
var json = JSON.parse(xhr.responseText);
document.getElementById('target').innerHTML = json['response']['players'][0]['personaname'];
} else {
alert('Request failed. Returned status of ' + xhr.status);
}
};
xhr.send();
Remember to place these scripts at the end of your document.
I'm just doing some tests in my browser to figure out what's going on - everything seems to be working correctly up until this line:
responseJson = JSON.parse(localReq.responseText);
When I evaluate this part: JSON.parse(localReq.responseText); I get the appropriate value. But when I evaluate "responseJson" it gives me an uncaught referenceerror and I can't figure out why.
function login()
{
userName = document.getElementById("_name").value;
password = document.getElementById("_password").value;
data = "userName=" + userName + "&" + "password=" + password;
localReq = new XMLHttpRequest();
localReq.open("POST", "http://universe.tc.uvu.edu/cs2550/assignments/PasswordCheck/check.php", true);
localReq.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
localReq.send(data);
response = document.getElementById("_login");
if (localReq.status == 200)
{
responseJson = JSON.parse(localReq.responseText);
}
}
You need to use an event listener on your AJAX request to handle the response from the server asynchronously via a callback. By not doing this you are checking for a response code of 200 before the server has responded.
function login(){
userName = "username";
password = "password";
data = "userName=" + userName + "&" + "password=" + password;
localReq = new XMLHttpRequest();
// use an event handler here
localReq.addEventListener("load", function(evt){
if (localReq.status == 200) {
responseJson = JSON.parse(localReq.responseText);
alert("Success: " + localReq.responseText);
} else {
alert("Not Success!= :(");
console.log(localReq);
}
});
localReq.open("POST", "http://universe.tc.uvu.edu/cs2550/assignments/PasswordCheck/check.php", true);
localReq.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
localReq.send(data);
}
See this jsFiddle: http://jsfiddle.net/wwsj3r4q/
function submitLogin(){
var username = document.getElementById('username').value;
var password = document.getElementById('password').value;
var testlabel = document.getElementById('testlabel').value;
var postStr = "username=" + username + "&password=" + password + "&testlabel=" + testlabel;
if (window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest();
} else {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
document.getElementById('mainPage').innerHTML = xmlhttp.responseText;//ATTENTION1
} else {
document.getElementById('mainPage').innerHTML = "Logining......";//ATTENTION2
}
}
xmlhttp.open("POST", "loginto.php", true);
xmlhttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
xmlhttp.send(postStr);
}
These are my codes.
If I change the "mainPage" into something else in the //ATTENTION2, the page will auto send a "GET" method, but if I still use the "mainPage" in there, there will be no problem.
However, if I change the "mainPage" into something else in the //ATTENTION1, there will have no problem with the post method, the response things can be shown in the correctly.
So, is there any solution? Thanks!
What does "something else" mean ? You need to have an id of an element in your page, where the content from the ajax response will be rendered.
For example, if you have a
<div id="myID"></div>
somewhere in the page, and change 'mainPage' in //ATTENTION1 to 'myID', then the response from the ajax request will be placed in that div.
The change you make in //ATTENTION2 is for intermediary states because it is on "else", so will not impact what happens when the ajax request is complete.