I have a php file, content.php, that is currently being loaded in the browser:
<html>
<head>
<title>Content</title>
<script src="content.js"></script>
</head>
<body>
<?php
if ( isset($_POST["status"]) && ($_POST["status"] === 1) ) {
?>
Content for users with status 1
<?php
} else {
?>
Content for users with different status
<?php
}
?>
</body>
</html>
What I want to do, is set the
$_POST["status"]
variable from within
content.js
I have thought about using a hidden html form and clicking the submit button through javascript, but that doesn't really seem like an elegant solution.
I have also thought about using an XMLHttpRequest, the problem being that I haven't found a way to send the data to the currently viewed/loading page through an XMLHttpRequest.
I am using no extra libraries, only javascript and php.
Is there a more elegant solution to my problem the a hidden html form?
Seems you need to work with AJAX because you need to execute server side script in hidden manner and update the html.
interface.php has content.js and a div
content.js send ajax post request with status
content.php sends the content according to status
interface.php's div is updated.
Here are the content.js and interface.php
let status = 1;
loadDoc(status);
function loadDoc(status) {
let xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = () => {
if (xhttp.readyState == 4 && this.status == 200) {
document.getElementById("content").innerHTML =
xhttp.responseText;
}
};
xhttp.open("POST", "content.php", true);
xhttp.send("status=" + status);
}
<html>
<head>
<title>Content</title>
<script src="content.js"></script>
</head>
<body>
<div id="content"></div>
</body>
</html>
And here is your content.php
<?php
if ( isset($_POST["status"]) && ($_POST["status"] === 1) ) {
?>
Content for users with status 1
<?php
} else {
?>
Content for users with different status
<?php
}
?>
Bingo! You set the $_POST["status"] via content.js
POST variables can only be passed in a request header. This means that it has to be either a form submission, as you already know, or an AJAX request. There is no way to have a separate client-side resource supply new information to an existing request.
Related
I am new to this, so far i was just using html form, click the submit button, the page was refreshing and the data was sented to the server (mySQL). But i learned Ajax (AJAX is a developer's dream) they are saying cause you can:
Read data from a web server - after the page has loaded
Update a web page without reloading the page
Send data to a web server - in the background
So i did a simple example. Let's say that i have set the sqlConnection.php
let input = document.getElementById("inputField");
document.getElementById("submitBtn").addEventListener("click", function (){
if(input.value == ""){
alert("empty field");
}else {
$(document).ready(function (){
$.ajax({
url: 'insert.php',
method: 'POST',
dataType: 'text',
data: { comment: input.value },
success: function (){
input.value = "";
}
});
});
}
});
function selectQuestions(){
let data = "true";
$("#comments").load("select.php");
}
setInterval(selectQuestions, 3000);
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Ajax text</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.0/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-wEmeIV1mKuiNpC+IOBjI7aAzPcEZeedi5yW5f2yOq55WWLwNGmvvx4Um1vskeMj0" crossorigin="anonymous">
</head>
<body>
<div class="container py-3">
<input id="inputField" type="text" class="form-control text-left" aria-label="">
<div class="py-2 my-1">
<button id="submitBtn" value="addNew" class="btn btn-success">Submit</button>
</div>
</div>
<div class="container" id="comments">
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="main.js"></script>
</body>
</html>
select.php has this:
$sql = "SELECT * FROM data";
$result = $conn->query($sql);
if (mysqli_num_rows($result) > 0) {
while ($row = mysqli_fetch_assoc($result)) {
echo "<p>{$row['question']}</p>";
}
} else {
echo "No comments";
}
So my Question: Is this correct in order to see new results that came from the server ? I call the setInterval method every 3 seconds as you can see. Is this bad for the server ? For example if i upload this project to a server and 10 users are using it.. am i exhausting the server - consuming more space ?
Assuming your code is in main.js, you don't need the $(document).ready(), since at the bottom of the <body>, your code will only run after everything is ready anyway. Not to mention it's in the wrong place.
At first I thought you were using .load() wrong, since its a shorthand for the event handler .on('load'). But it turns out in jquery 3.0 they've added an ajax method also called .load(). This is dumb and going to cause alot of confusion, but I digress, use $.get() or $.getJson to get things from a server.
Hitting the server with an interval isn't necessarily bad, it's called polling and it's how the internet did full duplex communication for many years. The problem comes when you poll too often or want to update too much data or have too many users all polling at once. How much is too much all depends on the machine your server is running on. Websockets is definitely a better option, but quite a bit more complex to configure.
I took the liberty to re-write some things, since if you're using jquery, might as well use jquery.
let $input = $('#inputField');
$('#submitBtn').on('click', function(e) {
e.preventDefault(); //assuming this is in a <form>, default action is to reload the page
if ($input.val()) {
$.post('insert.php', { comment: $input.val() })
.done(function() {
$input.val('');
})
.fail(function(error) {
//error handling code
});
} else {
alert("empty field"); //alerts are annoying and thread blocking,
} //maybe use a different method to communicate with the user.
});
setInterval(function() {
$.get('select.php')
.done(function(select) {
//whatever you want to do with the response from this
})
.fail(function(error) {
//error handeling code
});
}, 3000);
On the php side, maybe just clean things up a bit so that it's more readable. You can use the ->fetch_all(MYSQLI_ASSOC) method instead of a while loop to get an associated array for the result. Then just array_map() and implode() that to build you html response.
<?php
$conn = new mysqli("configs and what not");
$statement = $conn->query("SELECT * FROM data");
$result = $statement->fetch_all(MYSQLI_ASSOC);
if (count($result) > 0) {
echo implode("", array_map(fn($row) => "<p>{$row["question"]}</p>", $result));
} else {
echo "No comments";
}
$conn->close();
I have wrote a HTML/Javascript code generator but instead of outputting the code to a HTML site i would like the code to be send to php to be added to a database but i cant work out how to get the out put of the javascript into PHP
there is also another javascript doc to go with this if you need it to make it work ..
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<script src="../voucher_codes.js"></script>
</head>
<body>
<h1>pattern codes</h1>
<ul id="pattern-codes"></ul>
<script>
var patternCodes = voucher_codes.generate({
prefix: "BREAK-",
postfix: "-2019",
length:5,
count: 5,
charset: "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
});
function fillList(listId, items) {
var list = document.getElementById(listId);
items.forEach(function(item) {
list.innerHTML += "<li>" + item + "</li>";
});
}
fillList("pattern-codes", patternCodes);
</script>
</body>
</html>
i am wanting the output of the function "fillList" to send the output to PHP if this is possible....
You would have to look into using AJAX or the Axios library to send requests to a server page such as PHP.
Here is a simple AJAX POST server request in Javascript:
`
<script>
function loadDoc() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var response = this.responseText;
}
};
xhttp.open("POST", "request_page.php", true); // set method and page
xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); // set content type that we are sending POST data
xhttp.send("key=VALUE&key=VALUE"); // POST values
}
</script>
`
On the PHP page if you want to give a response of data to use back in Javascript, make sure to
json_encode($array_values)
the data array before echoing it out and set the headers to
header("Content-Type: application/json")
so you can grab the response data in Javascript and it can be turned into a Javascript {Object} or [Array]
I have an HTML file, and in the file, I have a javascript validate function to validate if the input of the text field in the other PHP file is blank or not. How can I use the 'gateway' name from myFile.html. This is what i have now:
myfile.html
<script type="text/javascript">
function Validate() {
if ((document.getElementsByName("gateway")[0].value == '')) {//I need to get access to "gateway" from myOtherFile.php
alert('Response required');
return false;
}
else { return true; }
}
</script>
myOtherFile.php
<div id="gatewayInput">
<form action="/action_page.php">
Gateway: <input type="text" name="gateway" placeholder="Gateway Name"><br>
</form>
</div>
#kkmoslehpour there are three ways
make an Ajax call
function Validate() {
var ajax = new XMLHttpRequest();
ajax.onreadystatechange = function() {
if(ajax.readyState == 4 && ajax.status == 200) {
var value_from_gateway = ajax.responseText;
}
}
ajax.send();
ajax.open("Get", "myOtherFile.php?value_from_gateway", true);
if ((value_from_gateway == '')) {//You have access now to "gateway" from myOtherFile.php
alert('Response required');
return false;
}
else { return true; }
}
create a redirect function on the myOtherFile.php on the top on the page -NECCESSARY
function redirect($location) {
header("Location: ". $location);
}
then program your myOtherfile.php to work with th $_GET and send the value
<div id="gatewayInput">
<form action="/action_page.php" method="post">
Gateway: <input type="text" name="gateway" placeholder="Gateway Name"><br>
</form>
</div>
<?php
if(isset($_GET['value_from_gateway'])) {
$gateway_value = $_POST['gateway'];
redirect('value_page.php?value_to_js='. $gateway_value);
}
?>
then create the whole value_page.php to echo the value on that same page;
<?php // This is all that there should be on this page
if(isset($_GET['value_to_js'])) {
echo $_GET['value_to_js']; //we are echoing this! it will be the response to the Ajax
}
?>
The ajax call wont have any problem with this, and whatever is display on the current page (value_page.php) will be sent as the response in myfile.php
I cannot comment but if you want to get info from your php file by your html file and javascript it could be done with ajax call to check what is inside php file and returns back with some info.
Otherwise you need to include that html file with script below your element with that name so you can use javascript to find that element and get its what you want.
You should put the validation code into the same file as the form, as it has to run on the client side. But if for some reason you really have to have it in a separate file (and that file only contains the script tag):
echo file_get_contents('myfile.html');
It is now magically in this file as well. But seriously just put it in the same file.
I saw the "likes" function in this demo blog and I'm trying to create a similar button. It seems that once hovering over this heart button, there will be a "finish" class added to the div containing it, so there must be a JavaScript that counts each like. I'd like to make it store each like per visitor (not more) on mouse click and remember it when reloading the page (so I guess there should be a cookie as well?).
It's done with ajax which store data to DB without page refresh and updates the value +1 at the same time
index.html (HTML File)
<html>
<head>
<script src="script.js"></script>
</head>
<body>
<button id="btn">Like</button>
</body>
</html>
script.js (Javascript File)
window.onload = function(){
document.getElementById('btn').addEventListener("click",
function(){
sendLike();
document.getElementById("btn").disabled = true;
});
}
function sendLike(){
var xhr;
if(window.XMLHttpRequest) xhr = new XMLHttpRequest();
else xhr = new ActiveXObject("Microsoft.XMLHTTP");
xhr.open("GET","like_counter.php?like=1",true);
if (xhr.readyState == 4 && xhr.status == 200) {
//handle what you want to do after the operation is completed here
}
xhr.send();
}
like_counter.php (PHP File)
<?php
if(!(isset($_GET['like'])&&$_GET['like']==1)){
die("Access denied!");
}
//This is just a demo. On a more practical situation,
//you would want to store the likes in a database and verify the authenticity
//of the request to prevent Cross-Site-Request-Forgery
session_start();
if(!isset$_SESSION['likes']) $_SESSION['likes'] = 0;
$_SESSION['likes'] += 1;
echo "done";
?>
suppose I work with some kind of API and my file server.php handles the connection to the API service. on my client side I use AJAX call like this:
$http({
url : 'server/server.php',
method : 'GET',
data : { getContent : true }
});
in my server.php I handle it like this:
if(isset($_GET['getContent'])){
$content = get_content();
}
function get_content(){...}
i just wonder what prevents any one send AJAX call with the same getContent parameter and get all my data? how can i secure it and make sure only calls from my application will get the relevant data back?
thank you!
I guess you are concerned about CSRF attacks. Read more about this here: https://www.owasp.org/index.php/Cross-Site_Request_Forgery_%28CSRF%29_Prevention_Cheat_Sheet
One of the mostly used option to secure your request will be:
- Generate a token and send it with the request for a session. This token can be identified by your WebServer as originating from a specific client for a specific session
2022 Update
This is a 7 year old post and the link in the link-only "accepted" answer is broken.
So, I'm going to offer a basic walkthrough and a complete model.
Remember, the $_SESSION will be preserved even in the AJAX handler, if it's all from the same domain. So, you can use that to check things.
Use $_POST
I presume you're using $_POST and not $_GET since you're concerned about security. If not, then much of this might not be important anyway.
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$post_method = true;
}
Ensure the $_SERVER['HTTP_REFERER'] is from your own site
if ( (!empty($_SERVER['HTTP_REFERER']))
&& ($_SERVER['HTTP_REFERER'] === "https://example.tld/my_sending_page.php") ) {
$from_my_server = true;
}
If you're not sure what this should be, run a test on your own server to see what this should be:
echo $_SERVER['HTTP_REFERER'];
Verify XMLHTTP/AJAX request via $_SERVER array
if ( (!empty($_SERVER['HTTP_X_REQUESTED_WITH']))
&& ( strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest') ) {
$ajax = true;
} else {
$ajax = false;
}
Use a token
This is the hard part, but not too hard.
Create the token
Set the token in $_SESSION
Put the token in the AJAX header
AJAX responder: confirm the AJAX header token with the $_SESSION token
send_from_me.php
// Create the token
//$token = md5(rand(10000,99999)); // Not recommended, but possible
$token = bin2hex(random_bytes(64));
// Store in SESSION
$_SESSION["token"] = $token;
// Assuming your AJAX is this
const AJAX = new XMLHttpRequest();
// This goes inside your AJAX function somewhere before AJAX.send
//
AJAX.setRequestHeader("ajax-token", "<?php echo $_SESSION["token"]; ?>");
//
// That creates $_SERVER['HTTP_AJAX_TOKEN'] which we can use later
ajax_responder.php
session_start(); // Must have
if ($_SERVER['HTTP_AJAX_TOKEN'] === $_SESSION["token"]) {
$token_match = true;
} else {
echo "No script kiddies!";
exit();
}
// Now it's safe for your AJAX responder to proceed
Let's put all of this into a working example
sending_from.php
<?php
session_start();
$token = bin2hex(random_bytes(64));
$_SESSION["token"] = $token;
?>
<!DOCTYPE html>
<html>
<head>
<title>My AJAX Sender</title>
</head>
<body>
<script>
function ajaxFormData(formID, postTo, ajaxUpdate) {
// Bind a new event listener every time the <form> is changed:
const FORM = document.getElementById(formID); // <form> by ID
const FD = new FormData(FORM); // Bind to-send data to form element
const AJAX = new XMLHttpRequest(); // AJAX handler
// This runs when AJAX responds
AJAX.addEventListener( "load", function(event) {
document.getElementById(ajaxUpdate).innerHTML = event.target.responseText;
} );
// This runs if AJAX fails
AJAX.addEventListener( "error", function(event) {
document.getElementById(ajaxUpdate).innerHTML = 'Oops! Something went wrong.';
} );
// Add your token header
AJAX.setRequestHeader("ajax-token", "<?php echo $_SESSION["token"]; ?>");
// Open the POST connection
AJAX.open("POST", postTo);
// Data sent is from the form
AJAX.send(FD);
}
</script>
<div id="ajax_changes">Replace me with AJAX</div>
<form id="ajaxForm">
<input type="text" name="the_simple_response">
<button type="button" onclick="ajaxFormData('ajaxForm', 'ajax_responder.php', 'ajax_changes');">Send my Secure AJAX</button>
</form>
</body>
</html>
ajaxcheck.inc.php
<?php
$mysite = 'https://example.tld';
// All in one test
if (($_SERVER['REQUEST_METHOD'] == 'POST')
&& ((!empty($_SERVER['HTTP_REFERER'])) && ($_SERVER['HTTP_REFERER'] === "$mysite/my_sending_page.php"))
&& ((!empty($_SERVER['HTTP_X_REQUESTED_WITH'])) && ( strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest'))
&& ($_SERVER['HTTP_AJAX_TOKEN'] === $_SESSION["token"])) {
$ajax_legit = true;
} else {
echo "No script kiddies!";
exit();
}
?>
ajax_responder.php
<?php
session_start();
// Do all that checking we're learning about by neatly including the file above
require_once('ajaxcheck.inc.php');
// Process your AJAX
echo $_POST['the_simple_response'];
?>
i just wonder what prevents any one send AJAX call with the same getContent parameter and get all my data?
Nothing. This URL is public thus anyone can make requests to it.
how can i secure it and make sure only calls from my application will get the relevant data back?
You can pass additional data (for example, some hashed value) that is verified on the server side.
$http({
url : 'server/server.php',
method : 'GET',
data : { getContent : true, hash : '0800fc577294c34e0b28ad2839435945' }
});
and
if(isset($_GET['getContent']))
{
if(isset($_GET['hash']) && validateHash($_GET['hash']))
{
$content = get_content();
}
}
function get_content(){...}
i just wonder what prevents any one send AJAX call with the same getContent parameter and get all my data?
The same way you would protect the data in any other request (e.g. with user authentication). There's nothing special about Ajax in regards to HTTP as far as the server is concerned.
how can i secure it and make sure only calls from my application will get the relevant data back?
You can't. The user can always inspect what their browser is asking the server for and replicate it.
Generally, people authenticate users rather than applications.