How to get response from PHP server asynchronously - javascript

First of all I know that there are many questions already regarding this.After reading all answers and trying it out ..but none of them worked.So I'm uploading a question here.Please don't delete it.
So,I created a html file with a form and then sent the form data using ajax jQuery to PHP file as follows.
$("#form-id").submit(function e() {
e.preventDefault();
var sdata=("#text_feild").val();
$.ajax({
url:"filename.php",
type:"POST",
data:sdata
});
//display the message sent by PHP
/*Use the data sent by PHP to perform
different function*/
Now I want PHP to send a message to js or html or anything else.Also, I want PHP to send some Boolean data which I will be using to perform some function.

If you want to send multiple data then you can do this by using array and send them json encoded and you will receive data in "success" callback function of ajax call
consider below example
ajax call
$("#form-id").submit(function e() {
e.preventDefault();
var sdata=("#text_feild").val();
$.ajax({
url:"filename.php",
type:"POST",
data:sdata,
async: true,
dataType: 'json',
success: function(data) {
console.log(data); // check result in console
$('#result').html((data.content) ? (data.content) : '???');
$('#result').prop('title', data.title);
$('#jsonstring').html('Json object: '+JSON.stringify(data));
},
error: function(jqXHR, textStatus, errorThrown) {
console.log(textStatus, errorThrown);
}
});
});
<?php
$result = array(
'title' => 'Title',
'status' => 0,
);
echo json_encode($result);
?>

You can use the powerful pure javascript browser native fetch api.
To retrieve text/html.
fetch("https://api.github.com/")
.then(function(response) { return response.text() })
.then(function(text) {
console.log(text)
})
To retrieve json.
fetch("https://www.reddit.com/.json").then(v => v.json()).then((function(v){
syn = JSON.stringify(v)
main.innerHTML += syn
})
)
<div id="main">
Server side the base of a json api would be:
if ($_GET["myapi"] != ""){
header('Content-Type: application/json');
header("Access-Control-Allow-Origin: *");
echo json_encode(["Hello","World"]);
exit;
}
Calling: mysite/?myapi=whatever
Output: ["Hello","World"], with a json header, and CORS enabled.
Learn more about javascript promise(s)

Related

Javascript/jquery ajax request

I have a problem with this Ajax request, it causes error during the call, it is not shown in console nor compiler.
Javascript code:
jQuery(document).ready(function(){
jQuery.get({
url: "https://nonsoloalimentatori.it/tools/download-center/index.php?sku="+sku,
dataType: "jsonp",
cache: true,
success: function(){
console.log("success");
},
error: function(){
console.log("error");
}
}).done(function(){
console.log("here");
})
})
PHP:
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Credentials:');
header('Content-Type: application/json');
function searchJson($sku){
$array = [];
$json = file_get_contents('./list.json'); //read the file contente
$json_data = json_decode($json,true); //creating the json objectt
$n_elementi = count($json_data); //count the number of object element
for ($mul = 0; $mul < $n_elementi; ++$mul){ //for every element it is
searched the sku
if($json_data[$mul]["sku"] == $sku)//and it is compared to the sku
given by user
{
array_push($array,$json_data[$mul]);//if it is true the element
is added to array
}
}
return $array; //it is returned
}
if(isset($_GET['sku'])){
$result=searchJson($_GET['sku']);
echo json_encode($result, JSON_PRETTY_PRINT);
}
On jsonp response from the server side, jquery expects it to be under a callback function.
Please use the following code to output the server response:
$callback_function_name = !empty($_GET['callback'])? $_GET['callback'] : 'callback';
echo $callback_function_name.'('.json_encode($result, JSON_PRETTY_PRINT).')';
Reason for the callback function is: cross domain ajax call is not allowed in javascript, so in jsonp the url is loaded the way we load a js script file(you can add script from different domains in your site). The loaded script is then evaluated. If plain data is printed, it does nothing. So it is passed to a callback function registered by the caller JS to process.
You can set your own callback function too by setting:
jsonp : "custom_callback_function_name"
inside the ajax function as a parameter.
In that case your server side output should be like:
custom_callback_function_name({...json_data...});

Unable to send JSON via AJAX

I made a function which counts how much time I spent on some page and where I came from. I collect all the data and save it into a JSON but when I try to send that JSON via ajax on the success it alerts me with an empty alert box, which means that nothing is being sent. I tried to add async to false because I use the onbeforeunload function but that doesn't work. I tried numberless combinations with AJAX setting but nothing is working.
HTML / JS
(function(){
var time,timeSite,endTime,seconds,testObject,retrievedObject,text;
window.onload=function(){
time= new Date();
}
window.onbeforeunload=function(){
endTime = new Date();
timeSite= time.getTime()-endTime.getTime();
seconds =Math.abs(timeSite/1000);
window.localStorage['seconds']=seconds;
text = 'Visitor accessed site directly.';
if(document.referrer == ''){
var link = text;
} else{
var link = document.referrer;
}
var url = window.location.href;
var main = {
'From': link,
'Current was' : url,
'Time Spent': seconds
}
$.ajax({
type: "POST",
data: {'data': main},
url: "http://localhost:8080/projectFour/test.php", //i use this page only to check if i receive data
contentType:'application/json',
success: function(data) {
alert(data);
},
error: function(xhr, ajaxOptions, thrownError) {
if (xhr.status == 200) {
alert(ajaxOptions);
}
else {
alert(xhr.status);
alert(thrownError);
}
}
});
}
})();
Test.php
<?php
if(isset($_POST['main'])) {
$obj = json_decode($_POST['main']);
//some php operation
echo $obj;
}
?>
Your test.php is looking for a POST variable called main, but you're sending one called data.
You can change the data part of the ajax call from:
data: {'data': main}
to
data: {'main': main}
and that should cause it to post the variable with main as the variable name.
Secondly, when you return the data, it would be better to return it as JSON again, otherwise it might mangle the result a bit.
Replace
echo $obj;
with
echo json_encode($obj);
And in the ajax replace
alert(data);
with
alert(JSON.stringify(data));
That will give you a view of the returned data structure as a string.
You should also consider returning something from PHP when the if statement is false, whether that be an error code, or some other response. Sending no response in this case isn't very helpful to the client side, and has hindered your debugging.

Header PHP not working after AJAX call from Javascript

so, this is probably a dumb question, but is it possible to execute the header function in a php file if I'm getting a response with AJAX?
In my case, I have a login form that gets error codes from the PHP script (custom error numbers hardcoded by me for testing) through AJAX (to avoid reloading the page) and alerts the associated message with JS, but if the username and password is correct, I want to create a PHP cookie and do a redirect. However I think AJAX only allows getting data, right?
This is my code:
JS
$.ajax({
type: 'POST',
url: 'validate.php',
data: $this.serialize(),
success: function(response) {
var responseCode = parseInt(response);
alert(codes[responseCode]);
}
});
PHP
if(empty($user)){
echo 901;
}else{
if(hash_equals($user->hash, crypt($password, $user->hash))){
setCookie(etc...); //this is
header('admin.php'); //what is not executing because I'm using AJAX
}else{
echo 902;
}
}
Please sorry if the question doesn't even make sense at all but I couldn't find a solution. Thanks in advance!
EDIT: I did not include the rest of the code to avoid complicating stuff, but if you need it for giving an anwser I'll add it right away! (:
You're right, you can't intermix like that. The php would simply execute right away, since it has no knowledge of the javascript and will be interpreted by the server at runtime, whereas the js will be interpreted by the browser.
One possible solution is to set a cookie with js and redirect with js as well. Or you could have the server that receives the login request set the cookie when the login request succeeds and have the js do the redirect after it gets a successful response from the server.
You can't do like that because ajax request process in backed and return the particular response and if you want to store the cookies and redirect then you should do it in javascript side while you get the response success
$.ajax({
type: 'POST',
url: 'validate.php',
data: $this.serialize(),
success: function(response) {
var responseCode = parseInt(response);
alert(codes[responseCode]);
window.location = "admin.php";
}
});
if(empty($user)){
setCookie(etc...); //this is
echo 901;
}else{
if(hash_equals($user->hash, crypt($password, $user->hash))){
echo response// what every you want to store
}else{
echo 902;
}
}
If the ajax response satisfies your condition for redirection, you can use below:
$.ajax({
type: 'POST',
url: 'validate.php',
data: $this.serialize(),
success: function(response) {
var responseCode = parseInt(response);
alert(codes[responseCode]);
window.location="%LINK HERE%";
}
});
It's kind of ironic that you use ajax to avoid loading the page, but you'll be redirecting in another page anyway.
test sending data in json format:
Javascript
$.ajax({
type: 'POST',
url: 'validate.php',
data: $this.serialize(),
success: function(response) {
if(response.success){
window.location="%LINK HERE%";
}else{
var responseCode = parseInt(response.code);
alert(responseCode);
...
}
}
});
PHP
header("Content-type: application/json");
if(empty($user)){
echo json_encode(['success' => false, 'code' => 901]);
}else{
if(hash_equals($user->hash, crypt($password, $user->hash))){
echo json_encode(['success' => true, 'data' => response]);
}else{
echo json_encode(['success' => false, 'code' => 902]);
}
}

Ajax data parse

I have a page with comments. By ajax, send a request to php page by. Php then scans the database... In general the standard logical operations. In any case, I meet php
echo '<script>show_info("my_text")</script>';
(show_info - js function which toggle info div and it displays my text).
And if all is well DB will transmit
echo 'ok';
My ajax success
success: function (data) {
if (data == "ok") {
document.write ("It's work!");
};
}
But unfortunately it does not work.
Maybe it is necessary somehow break the data into two parts, script and other text.
You're sending out the response straight away to the server with echo '<script>show_info("my_text")</script>'; as a response. because of this, data won't evaluate to 'ok'.
Instead, you should send back an array:
$ret = array(
'script' => 'show_info("my_text")',
'status' => 'ok'
);
echo json_encode($ret); // <--this should be done after all processing
Then in the ajax function you need to add the dataType parameter
$.ajax({
//etc
dataType: 'json',
success: function(data){
if(data.status == 'ok'){
eval(data.script);
}
}
});

Codeigniter ajax CSRF problem

I've made a simple autoload function that loads content when you scroll down on a website. However, there seems to be a few problems when i enable CSRF protection in Codeigniter.
I'm not using a form, so i don't know how i can send the token from A to B when i'm doing my post request as you scroll.
My JavaScript
if (location.href == baseurl) {
$(window).scroll(function(){
if ($(window).scrollTop() > $('body').height() / 2) {
if(doScroll == 1) {
$.post(baseurl + 'ajax/images',{'id' : ID}, function(data) {
$("#wrapper_content").append(data);
if(data == 'Det finnes ikke flere bilder i databasen, WTF!? Send inn forslag ASAP!') {
doScroll = 0;
}
ID++;
});
}
}
});
}
Since Codeigniter expects a TOKEN on all POST request i can't get this to work when CSRF i enabled. Any suggestions?
Error when CSRF is Enabled
Failed to load resource: the server responded with a status of 500 (Internal Server Error)
If i turn CSRF off, everything works great...
You might like to try this code I've used. It works great:
<script type="text/javascript">
$(function(){
$('.answerlist').each(function(e){
$(this).click(function(){
var valrad = $("input[#name=answer]:checked").val();
var post_data = {
'ansid': valrad,
'<?php echo $this->security->get_csrf_token_name(); ?>' : '<?php echo $this->security->get_csrf_hash(); ?>'
};
$.ajax({
type: "POST",
url: "<?php echo base_url(); ?>online/checkanswer",
data: post_data,
success: function(msg){
/// do something
}
});
});
});
});
</script>
As others say - you have to post the CSFR token name and its value with the AJAX request parameters. Here is a simple solution to append it automatically to every AJAX request.
Here is what I put on my main view, so this code is on every page before loading the other javascript files:
<script>
var csfrData = {};
csfrData['<?php echo $this->security->get_csrf_token_name(); ?>']
= '<?php echo $this->security->get_csrf_hash(); ?>';
</script>
<!-- ... include other javascript files -->
</body>
</html>
And here is a part of a javascript file that I include on every page:
$(function() {
// Attach csfr data token
$.ajaxSetup({
data: csfrData
});
});
If you want, you can echo both the token name and the hash somewhere appropriate. Something like this.
echo $this->security->get_csrf_token_name()
and
echo $this->security->get_csrf_hash()
Or, you could use form_open() as usual and use the hidden input that is generated for you from your javascript. Disabling the CSRF-functionality is the wrong way to go.
Having reviewed my situation I believe the best option is to use CSRF but reset the token on each attempt. Otherwise the ideas expressed earlier about re-using the cookie token would allow an attacker to resubmit data hundreds of times using the same token which defeats the object of the point.
As such I have created the following function:
public function resetCSRF(){
$this->security = null;
$_COOKIE[$this->config->item('csrf_cookie_name')] = null;
load_class('Security', 'core');
$this->security->csrf_set_cookie();
return $this->security->get_csrf_hash();
}
If for example an ajax based login form fails - call this function in your PHP and then on the javascript side that receives the failure (this solution uses Jquery and a getCookie function from w3schools) would then simply call:
$('input[name="csrf_test_name"]').val(getCookie('csrf_cookie_name'));
Basically what you need to do is get the expected csrf value from the cookie (named 'ci_csrf_token' by default), then post it along with your other data.
You would need to modify this line:
$.post(baseurl + 'ajax/images',{'id' : ID}, function(data) {
to:
$.post(baseurl + 'ajax/images',{'id' : ID,'ci_csrf_token' : $.cookie('ci_csrf_token')}, function(data) {
Might need to install the cookie addon (I'm not really sure; I use mootools). Here is more information: http://aymsystems.com/ajax-csrf-protection-codeigniter-20.
Previous suggestions work great, but rather than using a variable that you can apply in every data-post, I find it simpler to use the ajax-setting to automatically apply this token to every post:
$(document).ajaxSend(function(elm, xhr, s){
if(s.data){
s.data += '&';
}
s.data += '<?php echo $this->security->get_csrf_token_name(); ?>=<?php echo $this->security->get_csrf_hash(); ?>';
});
(works with jquery-1.9.1. I'm not sure about other jquery-versions)
The only problem with a few of the above answers is that a csrf token is only valid for one request, so if you make a post request via ajax and do not refresh the page you will not have the current csrf token for your next ajax post request. This is my solution:
In your CodeIgniter Controller:
$data = array('data'=> 'data to send back to browser');
$csrf = $this->security->get_csrf_hash();
$this->output
->set_content_type('application/json')
->set_output(json_encode(array('data' => $data, 'csrf' => $csrf)));
$data = the data to return to the browser
$csrf = new csrf token to be used by the browser for next ajax post request
Obviously you can output this in other ways but JSON is used mostly with ajax calls. Also include this token in every post response to be used for the next post request
Then in your next ajax request (javascript):
var token = data.csrf;
$.ajax({
url: '/next/ajax/request/url',
type: 'POST',
data: { new_data: 'new data to send via post', csrf_token:token },
cache: false,
success: function(data, textStatus, jqXHR) {
// Get new csrf token for next ajax post
var new_csrf_token = data.csrf
//Do something with data returned from post request
},
error: function(jqXHR, textStatus, errorThrown) {
// Handle errors here
console.log('ERRORS: ' + textStatus + ' - ' + errorThrown );
}
});
Also remember that where I've got csrf_token:token replace crf_token with the name of your token found in application/config/config.php on line that states $config['csrf_token_name'] = 'csrf_token';

Categories

Resources