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
}
})
Related
I have an form that when it sumits the data it echo "success", I used the success to trigger a redirect to another page but it is not working. I have tried everything. The else statement works fine but whatever i write in the if(data == "success") is not working including console.log and alert.`
continueBtn.onclick = () =>{
//Ajax code
let xhr = new XMLHttpRequest();// this will create a new XML Object
xhr.open("POST", "php/signup.php", true );
xhr.onload = () =>{
if(xhr.readyState === XMLHttpRequest.DONE){
if(xhr.status === 200){
let data = xhr.response;
if(data == "success"){
errorTxt.textContent = "Thuinsowofnd wsikenon";
window.location.href = 'users.php';
}else{
errorTxt.textContent = data;
errorTxt.style.display = "block";
}
}
}
}
//let's send form data through Ajax to Php
let formData =new FormData(form);//this will create a new form object
xhr.send(formData);// this will the form data
`
I have tried using windows.location.href = "users.php" but it still doesn't work
I have a registration form. The register.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 Location:index.php (good)
register.php
The problem is, if there is any error, the user will be redirected to register.php
and the echo alert shows there (on white page)
AJAX
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 the msg div(same page 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 echo errors (register.php) to be handled by AJAX
Please understand that im new & learning, i spent a week in this.
If you choose to resolve this, please fix based off register.php and ajax code
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);
}
});
I’m trying to submit a form with data to a php file without reloading the page. I also have some js code that changes the form name and values when the next btn is clicked. I had 10 questions all on 1 page and I got it to work with PHP but now I’m trying to get 1 question per page. I looked in the network tab and it looks like the xhr requests are being sent but in my database.php file I wrote $user_anwser = $_POST[‘quiz_1’]; and var dumped it and I get a NULL value. Here is the ajax code.
form.addEventListener("submit", function(e){
if (ind < 10){
e.preventDefault();
} else {
form.setAttribute("action", "results.php");
}
let data = new FormData(form);
let xhr = new XMLHttpRequest();
xhr.open('POST', '../private/database.php');
xhr.onload = function() {
if (xhr.status === 200) {
// if the response is json encoded
let response = JSON.parse(xhr.responseText); // i get a parse error there
if (response.message == 'valid') {
// redirect here
}
}
// }
xhr.send(data);
}
});
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 !