How to receive a PHP response in Javascript - javascript

I've been stuck on this for the past day and it feels like I am missing something.
My assignment is:
Create a php file register.php which allows users to input their Name, Last name, Username and Email(via an HTML form) and then do some server-side verification on this data.
This file would also serve as an html form where users could input the data.
For the Username input field I have to, on each keystroke, check if a user with that username already exists in my database.
This has to be accomplished using Javascript by sending a request to register.php with Ajax.
I know how to run the necessary query to search my database based on a certain username. That part is not a problem.
What I can't get to work is
using Javascript/Ajax to send a request to register.php
getting register.php to run a query based on the inputed username, since I don't know how to recieve the request
getting register.php to "return" a response without writing it out in the DOM
What I've tried so far:
let username= document.getElementById('username');
username.addEventListener('input', validateUsername);
function validateUsername(){
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
// Typical action to be performed when the document is ready:
console.log(xhttp.responseText);
}
};
xhttp.open("POST", "../obrasci/registracija.php", true);
xhttp.send("username="+username.value);
}
this part works and I'm getting the whole HTML document back. I know that because the whole structure is being printed into the console.
now this is the part that I can't get to work. In PHP I've got this so far and I can't get the script to do anything with the username.
if( isset($_POST['username']) ){
json_encode($_POST['username']);
}
Edit: I forgot to add that this site needs to process the data sent with ajax dynamically(if that username is taken, mark the input as not okay until the user chooses a username that's not taken).
That might be a problem in the way I'm using this since the if in PHP only gets tested on first load?
Any help is appreciated.

First, you can check whether or not the request was sent as a POST request (opening register.php in your browser will be a GET request).
You can wrap your form handling by something like this
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// check if username exists
if (isset($_POST['username'])) {
echo 'username: ' . $_POST['username'];
die;
} else {
echo 'no username';
die;
}
}
change the code accordingly, use echo json_encode($data) to return your data in JSON format.
In your request, you might need to add the right header to tell PHP how to interpret the body sent with the request.
function validateUsername(){
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
// Typical action to be performed when the document is ready:
console.log(xhttp.responseText);
}
};
// add this line
xhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhttp.open("POST", "../obrasci/registracija.php", true);
xhttp.send("username="+username.value);
}
Also, make sure you have the right naming. In your code example, you refer to your input as the variable username, but you add the event listener to kor_ime, I don't know if you updated something to english and forgot other parts of it for this question or if that is your actual code
let username= document.getElementById('username');
username.addEventListener('input', validateUsername); // here change kor_ime to username and update the function name, you can omit the extra function wrapper

Related

Is this the right way to use Ajax?

So I’m working on a To Do App and I used Ajax to send data to PHP when a task is clicked to be marked as completed. PHP then sends an SQL query to MySQL and changes the value in the completed column from 1 to 0 or visa vera. Originally, I tried to send a PHP header to go back to that page but it didn’t work so after the request was sent I wrote some JavaScript code to refresh the page and the task is now marked as completed and I have a css style for that. I was wondering, I thought the purpose of Ajax was to not have to reload the whole page so idk if I’m using Ajax wrong and there is a better way to do this? The project works but I just want some feedback on my code I guess.
main.js:
for(i=0; i < div.length; i++){
div[i].addEventListener("click", function(e){
let xhr = new XMLHttpRequest();
xhr.open('POST', 'process_complete.php', true);
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
let task_num = e.target.getAttribute("id");
xhr.onreadystatechange = function(){
if(xhr.readyState === 4 && xhr.status === 200){
location.reload();
}
}
xhr.send(JSON.stringify(task_num));
});
}
process_complete.php:
if(isset($_SERVER['HTTP_X_REQUESTED_WITH'])){
$data = file_get_contents('php://input');
$id = json_decode($data);
$sql = mysqli_query($conn, "SELECT * FROM tasks WHERE Num = '$id'");
if($sql === false){
printf("error: %s\n", mysqli_error($conn));
}
while($row = mysqli_fetch_row($sql)){
if($row[3] === "1") {
$mysqli_update = mysqli_query($conn, "UPDATE tasks SET Completed = 0 WHERE Num = '$id';");
} else {
$mysqli_update = mysqli_query($conn, "UPDATE tasks SET Completed = 1 WHERE Num = '$id';");
}
}
}
I thought the purpose of Ajax was to not have to reload the whole page
It is.
You are supposed to write JavaScript that modifies the DOM of the current page at the point where you have location.reload().
So there is a third step you may be missing. You have passed the data and fetched it into the PHP page, however you need to pass it back. In order to do that, you first place an echo inside the PHP page which will work in much the way that return works with a function in PHP. Once you have done that, you will need to make sure AJAX takes in that returned value, and then make sure you have a function that includes this AJAX and uses that value to replace, append, or removes whatever content the AJAX is using. This is a lot easier to do if you use an extension of AJAX like the .post() found in the JQUERY framework.

Passing XMLHttpRequest to PHP results in empty $POST

So far, I have been working on some code, and have been troubleshooting for awhile and I'm pretty sure my syntax is correct. I've been having to work around a broken testing environment so I can't use normal breakpoints to test this on the backend.
I have the following function in javascript:
function ns_submit_form_inpage(path, data){
var request = new XMLHttpRequest();
request.onreadystatechange = function() {
if (request.readyState == 4) {
alert("Message Sent");
}
}
request.open('POST', path, true);
request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
var temp_string = array_to_string(data);
alert("data:"+ temp_string);
request.send(data);
}
And the following code in PHP:
<?php
mail("my_email#example.com", "Array: ". print_r($_POST, true), "From:test#example.com");
?>
I call the function, pass my path in along with an array. I get an email and a proper alert, so I know my function is called and the right file is hit and fires. A also know that right before I send off the data, they data is properly in the keyed array (e.g. first_name::bob, last_name::doe). However, the email I receive reads "Array: Array()" and confirmation via my "Message Sent" alert.
I've narrowed down where I think my error could be, and I'm done to pretty much nothing left, it feels like the array is just disappearing into the ether of the internet.
I found my issue. As mentioned, I was sending the data as an array. Although PHP reads the accepted data as an array, and I'm sending an array, the method by which the array is sent (application/x-www-form-urlencoded) doesn't USE an array. It uses a string. So, I had to change the array into a string following the format of "first_name=bob&last_name=doe&foo=bar". Now it works.

Which is the correct way to check if a session is still running? Which are some ways?

So I have already had my first experience with Web Design, but there were some things I did in a certain way that I didn't like, mainly because of time. So anyway, I don't know which is the correct way to handle sessions. What I did in my previous project was to embed PHP into HTML and based on whatever was in $_SESSION, usually an id and a user type number, then I'd open or close parts of the website to the user, through embedded PHP.
However, this is not how I wanted to do this initially, at first what I wanted to do was to make a JavaScript code to send a request through AJAX to the server, and check if the session was still active, and based on that open/close parts of the website, but then I'd have to make a request on every page and every so often to make sure the user is logged in. Should I handle something like this client-side?
What are some other ways to check the session but without embedding PHP and using JavaScript instead to modify the HTML document.
To do this, all you need is an ajax request on loop and a php file to check the session.
The Javascript
function checkLogin(un) { //put this function in a loop of some sort depending on how you want to use it
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
logout(xmlhttp.responseText);
}
}
xmlhttp.open("GET", "checklogin.php?un=" + un, true);
xmlhttp.send();
}
function logout(resp) {
if (resp == "false") { //comparing actual text, not boolean
window.location.href = 'logout.php'; //destroy the session or something
}
}
The PHP file checklogin.php (very simple)
<?php
if ($_SESSION[$_GET['un']] != true) {
echo 'false';
}
?>
The php will depend on how you store your sessions, but in this case it is just using one session titled by their username that stores true if signed in. I would recommend making this more complex if you decide to actually use it.

Run a PHP function on success of AJAX request completion

I know that in JS, you can use the success of an AJAX function as the trigger to start other events...
So I have just loaded a new page using AJAX. And through this I have also passed some parameters, this is what I have passed:
xmlhttp.open("GET","register-form.php?one="+wordChoiceOne+"&two="+wordChoiceTwo+"&three="+wordChoiceThree,true);
So I now have the variables $one, $two, $three in PHP
I want to complete a couple of tasks using these (concatenate, capitalise, assign etc) before outputting onto the page. However I don't want this to be bound to the click of a button or anything, I want it to be bound to the success of the AJAX load.
How can I now start these actions in PHP?
Pseudo-code:
function setUsername() // RUN ON AJAX SUCCESS{
// capitalise first letter of one two and three
// concatenate together
// Store in variable $username
}
Then ECHO USERNAME OUT
ETA. I have already written the AJAX request and it works fine. Now it's loaded, I want to perform this PHP function, binding the trigger of that function to the success of the AJAX load:
<?php
$_GET['one'], $_GET['two'] and $_GET['three'];
// Capitalise first letter
$one = ucfirst($one);
$two = ucfirst($two);
$three = ucfirst($three);
$username = $one . $two . $three;
?>
EDIT: OK so it appears I can't explain myself, or I haven't understood what is required for this functionality. But here is what I need to happen in plain english, with links.
I am building a registration system. Instead of letting people type in their own username, I have a username builder. You can see this here:
http://marmiteontoast.co.uk/fyp/login-register/register-username-builder.php
Step One in Javascript
You drag the tiles into the boxes, hit the button that shows up. When you have all three, you hit the big green button. Up until this point, we are all in jQuery, and we have the following three variables stored:
wordChoiceOne - the first word you choose
wordChoiceTwo - the second word you choose
wordChoiceThree - the third word you choose
These are stored as JS variables.
Step Two PHP time
So now that I have these three stored variables I wish to move away from JS and start using PHP. I have already built a successfully working registration but it uses the username as an input rather than this when helps you "build" your own.
My research has led to the understanding that because of the client side to server side switch the only way that I can successfully pass these variables into PHP is through an AJAX request. This seems pretty handy to me because I would like the registration form I have already built to be loaded into the page asynchronously. So I asked for some advice about how to "share" these jQuery values through the AJAX request and was helped with the following, to pass them through the URL:
xmlhttp.open("GET","register-form.php?one="+wordChoiceOne+"&two="+wordChoiceTwo+"&three="+wordChoiceThree,true);
My understanding (and maybe I'm wrong? Please let me know and explain if I am...) is that this assigns the already existing variables of wordChoiceTwo etc to a PHP variable of $two. Is this right?
So now I have PHP variables $one, $two and $three...
Running the PHP
Perhaps this is because I am more used to working with JS, but with JS you have to do something (button click etc) to be able to enact a function. I know that one such do something is a successul AJAXC request but that isn't PHP. So my question... and this was really the only question I had, is ** how do you start the running of a PHP function when you've just loaded somethhing through AJAX?** I want to start running a php function called `setUsername" on this page. But I don't want the user to have to press a button to make this start, I want it to be bound to the success of the AJAX completion or something similar to this, as I understand that might be JS only.
This is the AJAX call I already have in place:
function saveUsername(wordChoiceOne, wordChoiceTwo, wordChoiceThree){
var xmlhttp;
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.getElementById("login-register-wrapper").innerHTML=xmlhttp.responseText;
}
}
xmlhttp.open("GET","register-form.php?one="+wordChoiceOne+"&two="+wordChoiceTwo+"&three="+wordChoiceThree,true);
xmlhttp.send();
}
Add a json header type and echo
$_GET['one'], $_GET['two'] and $_GET['three'];
// Capitalise first letter
$one = ucfirst($one);
$two = ucfirst($two);
$three = ucfirst($three);
$username = $one . $two . $three;
header('Content-type: application/json');
echo json_encode(array('username'=>$username)); // <---
then in your js, bind a function to the success of the call:
xmlhttp.onreadystatechange=function() {
if (xmlhttp.readyState==4 && xmlhttp.status==200) {
//xmlhttp.responseText;
}
}
edit, because there seems to be some confusion:
Just because an ajax call reaches your php script doesn't mean it's executed. The request by nature will sit and wait for a reply. This reply can contain data if your php echo's it.
edit 2 so you can wrap your head around the principle of it, here's an oversimplification of what I think you want:
file 'ajax.html':
<div id="name"></div>
<script>
function myName(first, last) {
var req = new XMLHttpRequest();
req.open('GET', 'ajax.php?first='+first+'&last='+last);
req.onreadystatechange = function() {
if(req.readyState==4 && req.status==200) {
data = JSON.parse(req.responseText);
document.getElementById('name').innerHTML = data.username;
}
}
req.send();
}
myName('john', 'doe')
</script>
file 'ajax.php':
$first = $_GET['first'];
$last = $_GET['last'];
header('Content-type: application/json');
echo json_encode(array('username'=>ucwords($first) . ' ' . ucwords($last)));
this is generally how AJAX is used

How to compare the two OrderIds in Google Wallet?

I am implementing Google Wallet for Digital Goods in a website, using PHP and HTML/JavaScript. I have achieved a successful Wallet transaction in the sandbox setting. So far, so good.
Now, in order to ensure the purchase is a secure transaction, I want to check whether the orderId that comes back in the successHandler is equal to the orderId received via a POST from Google in my postback file on the server.
I know a reasonable bit about PHP, less so about Javascript. After having studied all Google Wallet entries in StackOverflow and after having read over and over again the Google Wallet Merchant Setup pages, I still cannot figure out the proper code to compare the orderId coming from the successHandler and the orderId from the postback file. It seems to me that the successHandler's orderId (which I am guessing can be written as result.response.orderId which I have seen in other StackOverflow answers) is defined in Javascript, while the one from the postback file (which I call here postback-orderId) is defined in PHP.
How can you compare the two? One is a Javascript variable, the other a PHP variable.
I guess the best place to compare these variables is in the successHandler function. But how do I get a PHP variable from the postback file (called $orderId in that file) into a Javascript function which is used in another file?
I show what I have so far as my PURCHASE file and what I have as my POSTBACK file.
PURCHASE FILE
<?php
include ('sessionstart.inc');
require_once 'generate_token.php';
echo "
<!DOCTYPE html>
<html>
<head><meta name='viewport' content='width=device-width, initial-scale=1,maximum-scale=1'>
<title>Digital Goods Application</title>
<script src='https://sandbox.google.com/checkout/inapp/lib/buy.js'></script>
<script type='text/javascript'>
//Success handler
var successHandler = function(result){
if (result.reponse.orderId == postback-orderId) {
if (window.console != undefined) {
console.log('Purchase completed successfully.');
}
}
}
//Failure handler
var failureHandler = function(result){
if (window.console != undefined) {
console.log('Purchase did not complete.');
}
}
function purchase(jwt_value) {
runDemoButton = document.getElementById('runDemoButton')
google.payments.inapp.buy({
'jwt': jwt_value,
'success': successHandler,
'failure': failureHandler
});
return false;
}
</script>
</head>
<body>
<div>
<p>Buy 5 Search Credits to continue searching The Clock Register.</p><br />
<button id='runDemoButton' value='buy' class='buttons' onclick='purchase(\"$jwtToken\");'><b>Buy</b></button>
</div>
</body>
</html>";
?>
POSTBACK FILE
<?php
include ('sessionstart.inc');
include_once ('JWT.php');
$encoded_jwt = $_POST['jwt'];
$decodedJWT = JWT::decode($encoded_jwt,"mySecretKey");
$orderId = $decodedJWT->response->orderId;
header("HTTP/1.0 200 OK");
echo $orderId;
?>
</body>
</html>
Any help much appreciated!
You have to remember that the rendering of your page (and the buy action) happen long before the postback is dispatched / received by your server, as such, you can not have the postback-orderID in your page. You will have to do the following:
Your postback url target file / script should log the data received on your server (in a file or database).
You will need to write another php file / script on your server that can retrieve data from the logs in 1 above and does the comparison to check whether the orderID in the successHandler has been logged.
The success handler will have to make a call to the script in 2 above with, at least, the orderID as a parameter. (do not worry about the ajax call, it is simply javascript)
This may seem convoluted and long but can be achieved in less than 20 lines of code (both php and javascript / ajax).
EDIT
1. Updated postback.php to include logging
<?php
require_once 'JWT.php';
$encoded_jwt = $_POST['jwt'];
$decodedJWT = JWT::decode($encoded_jwt, $sellerSecret);
$orderId = $decodedJWT->response->orderId;
header("HTTP/1.0 200 OK");
echo $orderId;
$logfile = "logfile.txt";
if (!file_exists($logfile)) {
touch($logfile);
chmod($logfile, 0777);
}
$orderIDS = file($logfile); //reads file into array
$orderIDS[] = $orderId; //append new orderID to array
file_put_contents($logfile, $orderIDS); //save the new array to file
?>
EDIT 2
second script IDSearch.php to search for orderIds
<?php
$orderSearch = $_GET['orderID'];
$logfile = "logfile.txt";
if (file_exists($logfile)) {
$orderIDS = file($logfile); //reads file into array
echo (in_array($orderSearch, $orderIDS)); // either true or false is returned
} else {
echo 'Error';
}
?>
EDIT 3
Finally, amending your successhandler to call the IDSearch.php script
var successHandler = function (result) {
if (window.XMLHttpRequest) { // code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp = new XMLHttpRequest();
} else { // code for IE6, IE5
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
if (window.console != undefined) {
console.log(xmlhttp.responseText);
}
}
}
xmlhttp.open("GET", "IDSearch.php?orderID=" + result.reponse.orderId, true);
xmlhttp.send();
}
PS. In the handler, make sure you have the absolute path to the web resource of IDSearch.php
Am not a PHP developer so this is more "conceptual" than specific -
The overall idea is that you would persist the data you received from the (server side) POST from Google (aka "the PHP variable" you received at your postback url) somehow - e.g. a database.
You then have options on what to do next (to compare) -
perhaps an ajax call in your success handler to your server (that obtains the persisted data to) verify/compare the "javascript variable/orderId" with the "Php variable/orderId", before doing x
perhaps redirect in your success handler and send the "javascript orderId" as some value (query string, POST data, etc.) to a target that does the verification/comparison same as above (from server/db), and then do x
So its about persisting the data for later verification.
Hth....
Update (above disclaimer applies) :)
I set $orderId in the POST-back file into a SESSION as follows: $_SESSION['orderid'] = $orderId; However, when I check on the value of $_SESSION['orderid'] it is empty.
If I understood correctly, you're setting a Session Variable from Google's server-side Postback which means the request/session isn't "tied" to the browser/client. It was a server side POST - the browser, where the payment process is happening has no knowledge of it - it wasn't involved in the postback at all (the "client" in that case was some Google machine).
In other words, the browser has no "knowledge" of that (separate/server-side) "session", it either has no "sessionID" (cookie) nor one that would match (remember it was "some Google machine" that made the request when you set a session variable)
Hth....

Categories

Resources