Settup form script for ajax and post calls - php

i would like to know if its possible to set up my script so it can be handled by http ajax call and alternatively also the classic post way:
on the top i am first doing this:
if (isset($_SERVER['HTTP_X_REQUESTED_WITH']) AND strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest'){
$AnswerType = 'die';
}
if ($_SERVER['REQUEST_METHOD'] === 'POST'){
$AnswerType = 'session';
}
Then i check if either of these two is set by doing the following:
if ($AnswerType == 'die' || $AnswerType == 'session' ){
*here i run my script*
}
When the script ends i finally try to send all responses in my $respond_message array back the way the form where initialy posted:
if ($AnswerType = 'die'){
die(print_r($respond_message));
}
if ($AnswerType = 'session'){
$_SESSION['formrespondmessage'].= print_r($respond_message);
header("Location: /");
}

You want the script to react different on ajax and on simple post request? I think in this case the best solution is just to pass any variable, which indicates, that data is being sent by ajax. Like this:
postparams['ajax']=1;
$.post(...
And then in php make check like this:
if (isset($_POST['ajax'])) {
code for ajax request
} else {
code for simple post request
}

Not sure about your code, I prefer not to use so complicated scripts, at least you need to add () after serializeArray, possibly everything else looks ok. I would do like this:
<form name="form1" id="form1">
<input type="text" name="qq" value="ww">
</form>
<input type="button" onclick="dt=$('#form1').serializeArray();dt[dt.length]={name: 'ajax', 'value': 1};$.post('test.php', dt, function(data) {alert(data)});">
And in php file just check if isset($_POST["ajax"]). For example, my looks like this:
<?
if (isset($_POST["ajax"])) print_r($_POST);
?>

Related

PHP calling function with parameters by clicking on HTML div

I am trying to make a delete button which I'll be able to delete some user from my database but main thing how to call PHP function with clicking on some div etc..
<div class="cross" onclick='<?php deleteUser("Nickname")?>'>X</div>
<?php
function deleteUser($username) {
//... code
}
?>
Html can't directly call php, it can do a separate call to load the same page, with the action.
<?php
function deleteUser($username){}
if($_GET['action'] == "delete")
{
deleteUser($_GET['username']);
}
?>
<a class="cross" href='?action=delete&username=NickName'>X</a>
The reason for this is because PHP runs on the server, BEFORE anything is sent to the browser. So it requires another page load to run the function by clicking something. It is possible to use javascript and AJAX calls to send a call to a php script without reloading the main page. Just look into Jquery's post or ajax features.
You cannot call a PHP function that resides on the server by just clicking on a div that exists on the client browser.
You need to trigger a Javascript event (using e.g. jQuery), that will call a function on the server (e.g. through AJAX), that after checking the parameters are correct and the user has the right of calling it will do what you seek.
There are ready-made frameworks that would allow you to do that.
Otherwise (after including jQuery in your HTML page) you can do something like,
<div class="cross" id="deleteUserButton" data-user="nickname">X</div>
<script type="text/javascript">
$('#deleteUserButton').on('click', function() {
let nick = $(this).attr('data-user');
$.post('/services/delete.php',
{
cmd: 'delete',
user: nick
}).then( reply => {
if (reply.status === 'OK') {
alert("User deleted");
}
});
<?php
$cmd = $_POST['cmd'];
switch($cmd) {
case 'delete':
$user = $_POST['user'];
if (deleteUser($user)) {
$reply = [ 'status' => 'OK' ];
} else {
$reply = [ 'status' => 'failure', 'message' => 'Doh!' ];
}
break;
...
header('Content-Type: application/json;charset=UTF-8');
print json_encode($reply);
exit();

Prevent returns from ajax.php

In my ajax.php has:
if(urlvar(2) == 'uploadphoto'){
do... echo '<img... />';
}
But this functions is only called by a jquery, returning on a specific div.
But if I visit the URL: [http://localhost/projectname/ajax/uploadphoto], this page returns the result of function with some erros (because the parameters are sent by jquery)
How I can prevent returns, if the file is accessed without jquery?
*SOLVED:
Use this function in functions that cannot be accessed without jquery method.
function isHttpRequest()
{
if( #$_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest') {
return true; //acessed by jquery
}
exit; // or return false -> from access the file without method
}
When you access the file via jQuery, you write something like:
method: "get" or method:"post" (The default, if not specified, is GET, I think)
So, at the beginning of your ajax.php - put:
if(!$_GET){
//[...the ajax.php code, here ...]
}
I personally create a hash in every form
and i check if that hash is correct , this prevents people from submitting forms from other servers too and it may help in your situation
http://code.tutsplus.com/tutorials/secure-your-forms-with-form-keys--net-4753
if the hash is wrong then it's abviously not coming from the form that it should come from
Modify your ajax.php to check if the request is an ajax call.
if(empty($_SERVER['HTTP_X_REQUESTED_WITH'])
|| strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) !== 'xmlhttprequest') {
// not an ajax request
} else {
if(urlvar(2) == 'uploadphoto'){
do... echo '<img... />';
}
}
Or just check at the beginning of ajax.php

Jquery Ajax no response

When I try to get the response from a php file using Jquery ajax, I just get (an empty string) (Accdg. to Firebug console using console.log(data))
Here's the Html code:
<form action="test.php" method="POST" id="ajax">
<input type="text" name="field" />
<input type="submit" value="submit" name="submit" />
</form>
Here's the Jquery code:
$('#ajax').submit(function(e) {
e.preventDefault();
$.ajax({
type: 'POST',
data: $(this).serialize(),
url: 'test.php',
cache: false,
success: function(data) {
alert(data);
}
});
return false;
});
And the PHP code:
if ($_POST['submit'] == "submit")
{
echo 'Got your request';
}
Just basic. What frustrates me is that it's straightforward, I've done some research and still it doesn't work. I also want it to be as simple as possible.
Please enlighten me.
Don't check to see if you're in a POST situation by checking for fieldnames. That's incorrect - you might change your client-side form names and forget to update the PHP check.
The 100% reliable method is to use:
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
echo "Got your request";
}
However, since you just want to see if the server got pinged at all by your ajax call, why not do:
<?php
echo "Got your ", $_SERVER['REQUEST_METHOD'], " request";
Which'd just return Got your POST request or Got your GET request, etc...
As well, check your server log (or use HTTPFOX/Firebug Net tab, etc...) to see if that ajax request is actually going out and being received by the server.
The problem with the serialize() method is that it doesn't include the name of the button parameter which you use in your php script (submit=submit parameter). It doesn't do it because it doesn't know which button was clicked. This parameter is only included by the browser when you submit the form normally.
So one possibility is to manually attach this parameter as query string parameter:
url: 'test.php?submit=submit',
and in your PHP script:
if ($_GET['submit'] == "submit")
{
echo 'Got your request';
}

Ajax with tokens

How would you go about using tokens with the following?
$('#DIV').load('child.php?id='+id);
So that you couldn't access child.php straight from the browser and type child.php?id=1
If this is not possible with tokens would there be any other way?
Thought about XMLHttpRequest as follows:
var mygetrequest=new ajaxRequest();
mygetrequest.onreadystatechange = function(){
if (mygetrequest.readyState==4){
if (mygetrequest.status==200 || window.location.href.indexOf("http")==-1){
document.getElementById("DIV").innerHTML = mygetrequest.responseText;
} else{
alert("An error has occured making the request");
}
}
}
mygetrequest.open("GET", "child.php?id="+id, true);
mygetrequest.send(null);
Many thanks.
What you need is to check if the request is an ajax request (from load()) or not, this can be done by the following:
child.php:
if(isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
// it's an ajax request validate id and continue!
} else {
// this is not an ajax request, get out of here!
}
You could use jQuery post to send the parameters "behind the scene" and then check if the request was sent from a certain location or IP within the actual php file. If the location or IP does not have the authority to access it, simply output an error using e.g. the die() method before anything else has been output.

PHP header() redirect with POST variables [duplicate]

This question already has answers here:
PHP Redirection with Post Parameters
(8 answers)
Closed 9 years ago.
I'm working with PHP, and I'm making an action page which a form posts to. The page checks for errors, then if everything is fine, it redirects them to the page where the data has been posted. If not, I need to to redirect them back to the page they were at with an error and the POST variables. Here is the gist of how it works.
The HTML would look like this...
<form name="example" action="action.php" method="POST">
<input type="text" name="one">
<input type="text" name="two">
<input type="text" name="three">
<input type="submit" value="Submit!">
</form>
action.php would look like this...
if(error_check($_POST['one']) == true){
header('Location: form.php');
// Here is where I need the data to POST back to the form page.
} else {
// function to insert data into database
header('Location: posted.php');
}
In the case of an error, I need it to POST back to the first page.
I can't use GET, because the input will be too large.
I don't want to use SESSION, if possible.
Is this possible?
// from http://wezfurlong.org/blog/2006/nov/http-post-from-php-without-curl
function do_post_request($url, $data, $optional_headers = null)
{
$params = array('http' => array(
'method' => 'POST',
'content' => $data
));
if ($optional_headers !== null) {
$params['http']['header'] = $optional_headers;
}
$ctx = stream_context_create($params);
$fp = #fopen($url, 'rb', false, $ctx);
if (!$fp) {
throw new Exception("Problem with $url, $php_errormsg");
}
$response = #stream_get_contents($fp);
if ($response === false) {
throw new Exception("Problem reading data from $url, $php_errormsg");
}
return $response;
}
If you don't want to use sessions, the only thing you can do is POST to the same page. Which IMO is the best solution anyway.
// form.php
<?php
if (!empty($_POST['submit'])) {
// validate
if ($allGood) {
// put data into database or whatever needs to be done
header('Location: nextpage.php');
exit;
}
}
?>
<form action="form.php">
<input name="foo" value="<?php if (!empty($_POST['foo'])) echo htmlentities($_POST['foo']); ?>">
...
</form>
This can be made more elegant, but you get the idea...
It is not possible to redirect a POST somewhere else. When you have POSTED the request, the browser will get a response from the server and then the POST is done. Everything after that is a new request. When you specify a location header in there the browser will always use the GET method to fetch the next page.
You could use some Ajax to submit the form in background. That way your form values stay intact. If the server accepts, you can still redirect to some other page. If the server does not accept, then you can display an error message, let the user correct the input and send it again.
It would be beneficial to verify the form's data before sending it via POST. You should create a JavaScript function to check the form for errors and then send the form. This would prevent the data from being sent over and over again, possibly slowing the browser and using transfer volume on the server.
Edit:
If security is a concern, performing an AJAX request to verify the data would be the best way. The response from the AJAX request would determine whether the form should be submitted.
Use a smarty template for your stuff then just set the POST array as a smarty array and open the template. In the template just echo out the array so if it passes:
if(correct){
header("Location: passed.php");
} else {
$smarty->assign("variables", $_POST);
$smarty->display("register_error.php");
exit;
}
I have not tried this yet but I am going to try it as a solution and will let you know what I find. But of course this method assumes that you are using smarty.
If not you can just recreate your form there on the error page and echo info into the form or you could send back non important data in a get from and get it
ex.
register.php?name=mr_jones&address==......
echo $_GET[name];

Categories