I have a form like this:
<form action="process.php" method="post">
<input type="text" name="input" />
<button type="submit">Submit</button>
</form>
And I have an Ajax script like this:
$("button").click(function(event) {
var $ajaxData = {
"input-val" : $("input").val();
}
$.ajax({
type : "POST",
url : "process.php",
data : $ajaxData,
dataType : "json",
encode : true
});
.done(function($data) {
alert($data["stat"]);
});
event.preventDefault();
$("form").unbind();
});
Also a PHP script (process.php) where the form data is send:
<?php
if(isset($_POST['input-val'])) {
$data['stat'] = 'success';
echo json_encode($data);
}
?>
All is correct and set, but, if I want to stop the users of seeing or going (manually) to the "process.php" page I add a redirect function:
<?php
if(isset($_POST['input-val'])) {
$data['stat'] = 'success';
echo json_encode($data);
}
header('Location: index.php');
?>
That makes Ajax's request fail automatically. How can I stop users of going or seeing the PHP script?
As I said, the "event.preventDefault();" is stopping Ajax of sending the users to the PHP script, but users can go there by themselves.
The problem is, the script is expecting a JSON, while your "redirect" code sends a HTTP 301 to a HTML file. Ultimately, the AJAX XHR is not seeing your JSON, but gets the HTML output.
Revert back your code to how it was before:
<?php
if(isset($_POST['input-val'])) {
$data['stat'] = 'success';
echo json_encode($data);
}
Instead, do it in the AJAX handler:
.done(function($data) {
alert($data["stat"]);
if ($data["stat"] == "success")
location.href = 'index.php';
}) // And you are also missing a ) here.
According to comments:
If you are redirecting if the $_POST is not set, please use the else:
if (isset($_POST['input-val'])) {
$data['stat'] = 'success';
echo json_encode($data);
} else {
header('Location: index.php');
}
Related
I have the following button:
<input type="submit" name="kudos_button" value="★ Give kudos"/>'
And for testing purpose, I made a PHP script like this after the </html>:
<?php
if(isset($_POST['kudos_button'])){
$message = "Pressed";
echo "<script type='text/javascript'>alert('$message');</script>";
//and then execute a sql query here
}
?>
It all works fine, when pressing the kudos_button the message shows up. But the problem is that when the user refreshes the page, the message shows up again. And I get the following message:
The page that you're looking for used information that you entered.
Returning to that page might cause any action you took to be repeated.
Do you want to continue?
Any tips how I can avoid this, so the button does not press again when refreshing?
If you don't want to navigate to a new page, then you can't use a regular form submission.
Make the HTTP request with JavaScript instead.
e.g.
const form = document.querySelector("form");
const responseHandler = response => response.json();
const dataHandler = data => {
alert(data.message);
};
const submitHandler = event => {
event.preventDefault()
const data = new FormData(form);
const url = "/path/to/dedicated/webservice/that/returns/json";
fetch(url, { method: "POST", body: data }).then(responseHandler).then(dataHandler);
};
form.addEventListener("submit", submitHandler);
MDN has a guide on using fetch.
Then your server-side code would look something like:
<?php
// Execute a sql query here
header("Content-Type: application/json");
$message = "Pressed";
echo json_encode( [ message => $message ] );
Here is my solution:
<form name="form1" method="POST" action="<?php echo $_SERVER['PHP_SELF']; ?>" >
<input type="submit" name="kudos_button" value="★ Give kudos"/>
</form>
<?php
if(isset($_POST['kudos_button'])){
$message = "Pressed";
echo "<script type='text/javascript'>alert('$message');</script>";
//and then execute a sql query here
}
?>
Should be worke fine.
But you should know that PHP works regardless of the alert. Either way, your SQL statement will be executed after the button is pressed.
JavaScript is a Client Based Script and PHP a Server Based Script two different things.
--- EDIT ---
I builded a Function Based PHP Script which is calling the alert and feel for 5 seconds to sleep so the alert can shown up.
Here is my finished solution:
<form name="form1" method="POST" action="./" >
<input type="submit" name="kudos_button" value="★ Give kudos"/>
</form>
<?php
if(isset($_POST['kudos_button'])){
session_start();
$_SESSION["Button_onClick"] = 1;
$message = "Pressed";
if ($_SESSION["Button_onClick"] == 1) {
Button_onClick();
$_SESSION["Button_onClick"] = 0;
if ($_SESSION["Button_onClick"] == 0) {
BackLoop();
}
}
}
Function Button_onClick(){
$message = "Pressed";
echo ("
<script type='text/javascript'>
alert('$message');
</script>
");
SQL_Statement();
}
Function SQL_Statement() {
//and then execute a sql query here
}
Function BackLoop() {
session_destroy();
echo("
<script>
setTimeout(function () {
//Redirect with JavaScript
window.location.href= './';
}, 5000);
</script>
");
}
?>
Just in case for that someone have questions. I added the setTimeout function so I could see the changes on the website. If you don't want any infos after the alert (user case), you can delete the function. You only need window.location.href= './';.
I have a button on my user.php page. This button must call action.php?name=john&id=10 onclick without refresh the page.
The page action.php should proccess this querystring data (name=john & id=10), perform some action and send an message back..
user.php example:
<button onclick="callAction()">Do it!</button>
function callAction() {
//call action.php?name=john&id=10
}
action.php example:
<?php
$name = $_GET['name'];
$id = $_GET['id'];
if(id == 10) {
//send user.php some successful text
} else {
//send user.php some error text
}
?>
Any idea? Thanks a lot!
Using jQuery you can make the ajax call like:
$.get('action.php?name=john&id=123', function (data) {
console.log('response: ', data);
});
Here is the documentation: https://api.jquery.com/jquery.get/
I'm trying to use AJAX to check variables in the database, and if it's true, then it should make it header to a certain page, except in this testing phrase, I'm not checking any variables. I'm just testing if it'll header off to that certain page if I call the function. I started at test1.php, but it should've called the ajax function, and immediately header off to test3.php, but it didn't. I'm not sure what I did wrong. Please take a look:
ajax.php
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script type = "text/javascript">
function nopassAjax(url,timeout) {
$.ajax({
type: "POST",
url: url,
error: function(xhr,status,error){alert(error);},
success:function(data) {
setTimeout(function() { timeoutAjax(url,timeout); }, timeout);
}
});
}
</script>
test1.php
<?php
include('ajax.php');
echo "<script>";
echo "nopassAjax('test2.php',1000);";
echo "</script>";
?>
test2.php
<?php
//checks some stuff in the database
//if true, header off to test3.php
header("Location: test3.php");
?>
test3.php
<?php
echo "Hello";
?>
From your question I'm assuming you want to redirect to the page that's returned from your AJAX call. You can't do this from PHP alone.
Javascript:
$.ajax({
method: "POST",
url: someUrl
}).fail( function( error ) {
alert( error );
}).done( function( response ) {
window.location = response;
});
PHP:
<?php
echo "test3.php";
?>
The idea is that this script POSTs the value of the text input in my html form to emailform.php, which takes that data and adds it to a .txt file. I think what I'm having trouble with is setting the value of $email in the PHP to that of the html text input. As a result, currently when the script is triggered I get two alerts (first 'error' then 'complete', from the .fail and .complete functions) and then the page reloads. That's why I think the problem is with the information being returned from the PHP but maybe I'm wrong.
<form method="post">
<input type="text" name="email" value="" class="emailSubmitSidebar" placeholder=" Your Email">
<input type="submit" name="submit" value="Add" class="submitButton" id="subscribeButton">
</form>
<script type='text/javascript'>
$(document).ready(function() {
var subscribeButton = $('#subscribeButton');
subscribeButton.click(function() {
$.ajax({
url: 'emailform.php',
type: 'POST',
dataType: 'text',
data: {email: $("input[name=email]").val()},
})
.done(function(data) {
alert("Added!");
})
.fail(function() {
alert("error");
})
.always(function() {
alert("complete");
})
})
})
</script>
And below is the PHP, I've added the first two lines to check for any errors, of which there are none anymore. What's strange is that when I run the PHP separately, the echo line prints the number 3 on the page without any apparent cause. I commented out the variable $email because I was led to believe it was better/necessary to first check if it isset.
<?php
ini_set('display_errors', 'On');
error_reporting(E_ALL);
$fileHandle = fopen('emailList.txt', 'a') OR die ("Can't open file\n");
$email= isset($_POST['email']) ? $_POST['email'] : "";
// $email=$_POST['email'];
$result = fwrite ($fileHandle, "$email; \n");
fclose($fileHandle);
echo (!$result) ? "error" : $result;
die;
?>
I think there is something wrong with your data, try to serialize it into a json data array:
var data = $(form).serialize();
$.ajax({
url: 'emailform.php',
type: 'POST',
dataType: 'text',
data: data,
})
The values will be sent as a normal post request, so the email address will be in $_POST['email'];
Updated from here
The jquery .done() and .fail() functions require http status codes to work, so your php file should return these codes. When a request is made and succeeded anything in the 200 range will be ok. While on an error, something from the 400 or 500 range should be returned. There is a full list here: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
So the ajax .success function is fired when 2xx is returned (replace .done with .success) and the .error is called when status code 4xx or 5xx is returned. See php below how to implement this.
The number 3 you are getting is the $return value of the fwrite function, according to: http://nl3.php.net/fwrite
fwrite() returns the number of bytes written, or FALSE on error.
Make your php like this:
<?php
//ini_set('display_errors', 'On');
//error_reporting(E_ALL);
if($fileHandle = fopen('emailList.txt', 'a')) {
if(isset($_POST['email']) && !empty($_POST['email'])) {
$email = $_POST['email'];
$result = fwrite ($fileHandle, "$email; \n");
fclose($fileHandle);
if(isset($result) && !empty($result)) { // Something was written
http_response_code(200);
echo "File written";
} else { // Writing failed
http_response_code(500);
echo "Writing of file failed";
}
} else { // Empty email
http_response_code(500);
echo "Email was empty";
}
} else { // File could not be opened
http_response_code(500);
echo "File could not be opened for writing";
}
?>
(Simple)
Change HTML to:
<input type="text" name="email" value="" class="emailSubmitSidebar" placeholder=" Your Email">
Change JS to :
$.ajax({
url: 'emailform.php',
type: 'POST',
dataType: 'text',
data: {email: $("input[name=email]").val()}
})
.done(function(data) {
// there checking
alert("success!")
})
Change PHP to:
$fileHandle = fopen('emailList.txt', 'a') OR die ("Can't open file\n");
$email=$_POST["email"];
$result = fwrite ($fileHandle, "$email; <br/>");
fclose($fileHandle);
echo (!$result)? "error" : $result;
die;
I have used the following guide to ifugre out how to send emails with file uploading without refreshing the page: http://viralpatel.net/blogs/ajax-style-file-uploading-using-hidden-iframe/ and it works fine, except that I'd like to be able to take a message from the php I use to upload the file and send the email, so that I can display that message to the user, on the page where they submitted the form from.
I have this code currently in my contact.php page:
if (!$sentMail) {
header('HTTP/1.1 500 Couldnot send mail! Sorry..');
exit();
} else {
echo '<h3>Hi ' . $postName . ', Thank you for your email</h3>
<p>Your email has already arrived in our Inbox, all We need to do is Check it.
<br />Good day.</p>';
}
The only problem is getting that message that I've echoed to show up where I'd like it to go. Any help would be greatly appreciated.
The PHP in the iFrame should post unique sessionID in the database with result.
In the meanwhile you can do an Ajax call to check the database if the mail is sent.
So we got 3 files
Your form (like index.html)
Your Mailer in iframe (like sendMail.php)
Your status checker (like getStatus.php)
Here we go..
Your IFRAME Mailer:
<?php
session_start();
$_SESSION['mailsender'] = mt_rand();
// this is ur iframe mailer
// here your mail send stuff .....
// if mail is sent
mysql_query("INSERT INTO mailsender (mailid, result) VALUES ('".$_SESSION['mailsender']."', 'successfull')");
// if mail fails
mysql_query("INSERT INTO mailsender (mailid, result) VALUES ('".$_SESSION['mailsender']."', 'failed')");
?>
getStatus.PHP :
<?php
session_start();
// check status and give JSON back
// getStatus.php - we be called from front-end
$query = mysql_query("SELECT * FROM mailsender WHERE mailid = '".$_SESSION['mailsender']."'");
$result = "Pending";
if (mysql_num_rows($query) > 0) {
while ($row = mysql_fetch_array($query)) {
$result = $rij['result'];
}
}
echo json_encode(array("result"=>$result));
?>
Your Front-end like Index.html:
<!DOCTYPE html>
<html>
<!-- include jQuery -->
<script>
$(document).ready(function(){
checkMailStatus = function() {
$.ajax({
url: 'getStatus.php',
dataType: 'JSON',
success: function(data) {
if (data['result'] == "successfull") {
// do successfull stuff here
// also clear the interval
}
if (data['result'] == "failed") {
// do failed stuff here
}
if (data['result'] == "pending") {
// still trying to send
// do stuff here while sending (like loading.gif)
}
}
})
}
$(".sendmailbutton").click(function(){
setInterval(function(){
checkMailStatus();
}, 800)
})
})
</script>
</html>