Reverse Ajax implementation using php - php

I am looking to implement reverse ajax in my application which is using PHP and jquery. I have googled a bit about it and found XAJA but that seems to be a paid application. Is there an open source application available for the same or has someone implemented it?
Some pointers or hints would be very helpful.
Thanks in advance.

I know of two types of reverse AJAX:
1- Polling
2- Pushing
I think polling is rather easier to implement, you just have your javascript make a regular request to the server every time interval, and when the server have some data for it it will respond. Its like a ping and some call it heartbeat, but its the very obvious solution for this problem. However it may easily overload the server.
EDIT Simple polling Example code:
Server-Side:
<?php
//pong.php php isn't my main thing but tried my best!
$obj = new WhatsNew();
$out = "";
if ($obj->getGotNew()){
$types = new array();
foreach ($obj->newStuff() as $type)
{
$new = array('type' => $type);
$types[] = $new;
}
$out = json_encode($types);
}
else{
$out = json_encode(array('nothingNew' => true));
}
Client-Side:
function ping(){
$.ajax(
{
url : "pong.php",
success : function (data){
data = JSON.parse(data),
if (data['nothingNew'])
return;
for(var i in data){
var type = data[i]['type'];
if (type && incomingDataHandlers[type]){
incomingDataHandlers[type]();
}
}
});
}
incomingDataHandlers = {
comments: function () {
$.ajax({
url: "getComments.php",
method: "GET",
data: getNewCommentRequsetData() // pass data to the server;
success : function (data){
//do something with your new comments
}
});
},
message: function (){
$.ajax({
url: "getMessages.php",
method: "GET",
data: getNewMessageRequestData() // pass data to the server;
success : function (data){
//do something with your new messages
}
});
}
}
$(docment).ready(function () {
setInterval(ping, 1000);
})

You are looking for what they call "long poll" - I did a "long poll php" and I got this thread on stack overflow:
How do I implement basic "Long Polling"?

you could websockets in conjuction with "flash" websockets because almost all browser have flash on board(average around 96%? => http://www.statowl.com/flash.php) => https://github.com/gimite/web-socket-js. You could use this together with http://code.google.com/p/phpwebsocket/. Still I am wondering if the performance is going to be any good. If it all possible I would use node.js to do reverse ajax. http://socket.io is a really cool project to do this!

Have you checked APE ?
Its a push based real-time data streaming technology over a single low volume ajax connection. The concept is useful, you may be able to replicate the same thing with your server-side implementation

Related

Display POST data in HTML element

I need some example to display POST data inside HTML DIV element. Like this: Beeceptor
I make an example using PHP and jQuery.
It works fine but I don't know if there a better solution instead of using SESSIONS and interval function?
The POST data is made by using an external program (not by jQuery itself).
PHP
session_id('13245');
session_start();
$session_id = session_id();
if($data['payload'] !== null)
{
$_SESSION['payload'] = $data['payload'];
$_SESSION['timestamp'] = microtime();
}
else
{
$_SESSION['payload'] = $_SESSION['payload'];
$_SESSION['timestamp'] = $_SESSION['timestamp'];
}
echo json_encode(array('timestamp' => $_SESSION['timestamp'], 'payload' => $_SESSION['payload']));
?>
jQuery
$(document).ready(function () {
var oldTimeStamp = 0;
setInterval(function()
{
$.ajax({
type:"post",
url:"post.php",
datatype:"json",
success:function(data)
{
var obj = jQuery.parseJSON(data)
if(oldTimeStamp != obj.timestamp)
{
oldTimeStamp = obj.timestamp;
$('#displayData').append('timestamp: ' + obj.timestamp);
$('#displayData').append(' rawPayload: ' + obj.payload);
$('#displayData').append('<br />');
}
}
});
}, 1000);//time in milliseconds
});
Any help will be greatly appreciated.
you can go for "then()" or "done()", immediate after finishing ajax call. here is the sample:
$.ajax({
type:"post",
url:"post.php",
datatype:"json",
success:function(data)
{...}
}).then(function (data){
var obj = jQuery.parseJSON(data)
if(oldTimeStamp != obj.timestamp)
{
oldTimeStamp = obj.timestamp;
$('#displayData').append('timestamp: ' + obj.timestamp);
$('#displayData').append(' rawPayload: ' + obj.payload);
$('#displayData').append('<br />');
}
});
You are trying to make a real-time application such as chatting and real-time visualizations. In order to achive this I suggest you to write with NodeJs SOCKET.IO
If you use PHP it will make your server lode more harder than JavaScript programs like socket.io.
Your Question:
It works fine but I don't know if there a better solution instead of using SESSIONS and interval function?
Answer:
Definitely it's a bad practice which trigger the server every seconds even there are no new updates. Let's assume you have 100 users online at the same time so your server will be called 100 times every second which is really a more load to the server.
Example:
https://socket.io/get-started/chat

Never-ending ajax request, good idea / bad idea?

For the backend of my site, visible only to a few people, I have a system whereby I communicate with a php via ajax like so:
function ajax(url, opts) {
var progress = false, all_responses = [], previousResponseLength = "";
var ajaxOptions = {
dataType: "json",
type: "POST",
url: url,
xhrFields: {
onprogress: function(e) {
if (!e.target.responseText.endsWith("\n")) return;
var response = e.target.responseText.substring(previousResponseLength).trim();
previousResponseLength = e.target.responseText.length;
var responses = response.split(/[\r\n]+/g);
var last_response;
for (var k in responses) {
if (responses[k] === "---START PROGRESS---") {
progress = true;
if (opts.onProgressInit) opts.onProgressInit();
} else if (responses[k] === "---END PROGRESS---") progress = false;
else all_responses.push(last_response = responses[k]);
}
if (progress && last_response !== undefined) opts.onProgress(JSON.parse(all_responses[all_responses.length-1]));
}
},
dataFilter: function(data){
return all_responses[all_responses.length-1];
}
}
$.extend(ajaxOptions, {
onProgress: function(data){
console.log(data);
}
});
return $.ajax(ajaxOptions);
}
And an example of a never-ending php script (until the user closes the connection):
const AJAX_START_PROGRESS = "---START PROGRESS---";
const AJAX_END_PROGRESS = "---END PROGRESS---";
session_write_close(); //fixes problem of stalling entire php environment while script runs
set_time_limit(0); //allows to the script to run indefinitely
output(AJAX_START_PROGRESS);
while(true) {
output(json_encode(["asdasd" => "asasdas"]));
sleep(1);
}
function output($msg) {
echo preg_replace("`[\r\n]+`", "", $msg).PHP_EOL;
ob_flush(); flush();
}
This allows me through 1 ajax request to 'poll' (am I using that term correctly?)
So if I want to execute a very long php script I can now check its progress, and the last response is delivered via jqhxr.done(callback).
Or, as in the example php script, I can open a connection and leave it open. Using sleep(1); It issues an update to the $.ajax object every 1 second.
Every response has to be json encoded, and if the response is 1 very long json that comes over multiple 'onprogress' calls, it waits until the end of the message (if responseText.endsWith("\n")) we're ready!)
My remote shared server didn't allow websockets so I made this. If the user closes the connection, so does the php script.
It's only got to work for a few admins with special privileges, and I don't need to worry about old browsers.
Can anyone see anything wrong with this script? Through googling I haven't found anybody else with this kind of method, so I expect something is wrong with it.
Extensive testing tells me it works just fine.
You invented long polling request, actually it's wide used as fallback to websockets, so nothing wrong with it.
About your code it's hard to say without testing, but when using such methods as long-polling, you need to double check memory leaks on browser side and on server side.

Is there a JavaScript way to do file_get_contents()?

Here is the PHP documentation
Here is how I would use it in an Ajax call, if I don't find a pure client way to do this.
$homepage = file_get_contents('http://www.example.com/');
echo $homepage;
Is there way to do this client side instead so I don't have to ajax the string over?
you could do
JS code:
$.post('phppage.php', { url: url }, function(data) {
document.getElementById('somediv').innerHTML = data;
});
PHP code:
$url = $_POST['url'];
echo file_get_contents($url);
That would get you the contents of the url.
It's 2020 and some modern approach;
async function file_get_contents(uri, callback) {
let res = await fetch(uri),
ret = await res.text();
return callback ? callback(ret) : ret; // a Promise() actually.
}
file_get_contents("https://httpbin.org/get", console.log);
// or
file_get_contents("https://httpbin.org/get").then(ret => console.log(ret));
JavaScript cannot go out and scrape data off of pages. It can make a call to a local PHP script that then goes on its behalf and grabs the data, but JavaScript (in the browser) cannot do this.
$.post("/localScript.php", { srcToGet: 'http://example.com' }, function(data){
/* From within here, data is whatever your local script sent back to us */
});
You have options like JSONP and Cross-Origin Resource Sharing at your disposal, but both of those require setting up the other end, so you cannot just choose a domain and start firing off requests for data.
Further Reading: Same origin policy
This function will return the file as a string just like the PHP file_get_contents().
function file_get_contents(uri, callback) {
fetch(uri).then(res => res.text()).then(text => callback(text));
}
However unlike PHP, JavaScript will go on to the next statement, not waiting for the data to return.
Not in a general sense. Cross-domain restrictions disallow Javascript code from doing this.
If the target site has CORS (cross-origin resource sharing) set up, you can use XMLHttpRequest to load files. Most sites do not, as it's off by default for security reasons, and is rarely necessary.
If you just need to include an HTML page, you can stick it in an <iframe> element. This is subject to some layout gotchas, though (the page ends up in a fixed-size element).
Or You can use php.js library. Which allow some php functions for javascript. file_get_contents() function one of them.
<script>
var data = file_get_contents('Your URL');
</script>
You can find more info about php.js : http://phpjs.org/
I think this may be useful for you:
An npm package with the "file-get-contents" method for node.js
https://www.npmjs.com/package/file-get-contents
It is asynchronous so if you are using express it should be used like this
app.get('/', async (req, res)=>{
//paste here the code below
}
Example
const fileGetContents = require('file-get-contents');
// A File request
try {
let data = await fileGetContents('/tmp/foo/bar');
console.log(data);
} catch (err) {
console.log('Unable to load data from /tmp/foo/bar');
}
// Or a HTTP(S) request
fileGetContents('https://pokeapi.co/api/v2/pokemon/1/').then(json => {
const pokemon = JSON.parse(json);
console.log(`Name of first pokemon is ${pokemon.name}`);
}).catch(err => {
console.err(`Unable to get content from PokeAPI. Reason: ${err.message}`);
});
<div id="svg">
</div>
<script>
function file_get_contents(uri, callback) {
fetch(uri).then(res => res.text()).then(text =>
{
var xmlSvg =text;
console.log(xmlSvg );
document.getElementById('svg').innerHTML = xmlSvg;
})
}
var uri ='You-urlllllllll-svg';
file_get_contents(uri);
</script>
function file_get_contents(filename) {
fetch(filename).then((resp) => resp.text()).then(function(data) {
document.getElementById("id").innerHTML = data;
});
}
file_get_contents("url");
<span id="id"></span>

Load PHP function with jQuery Ajax

I have a file which is loaded at the top of my document, which is called Videos.php. Inside that file are several functions, such as getYoutubeVideos. On some pages, I need to call upon that function several times (up to 50), and it of course creates major lag on load times. So I have been trying to figure out how to call that function in, only when it is need (when someone clicks the show videos button). I have very little experience with jQuery's ajax abilities. I would like the ajax call to be made inside of something like this:
jQuery('a[rel=VideoPreview1).click(function(){
jQuery ("a[rel=VideoPreview1]").hide();
jQuery ("a[rel=HideVideoPreview1]").show();
jQuery ("#VideoPreview1").show();
//AJAX STUFF HERE
preventDefault();
});
Ok I have created this based on the responses, but it is still not working:
jQuery Code:
jQuery(document).ready(function(){
jQuery("a[rel=VideoPreview5]").click(function(){
jQuery("a[rel=VideoPreview5]").hide();
jQuery("a[rel=HideVideoPreview5]").show();
jQuery.post("/Classes/Video.php", {action: "getYoutubeVideos",
artist: "Train", track: "Hey, Soul Sister"},
function(data){
jQuery("#VideoPreview5").html(data);
}, 'json');
jQuery("#VideoPreview5").show();
preventDefault();
});
jQuery("a[rel=HideVideoPreview5]").click(function(){
jQuery("a[rel=VideoPreview5]").show();
jQuery("a[rel=HideVideoPreview5]").hide();
jQuery("#VideoPreview5").hide();
preventDefault();
});
});
And the PHP code:
$Action = isset($_POST['action']);
$Artist = isset($_POST['artist']);
$Track = isset($_POST['track']);
if($Action == 'getYoutubeVideos')
{
echo 'where are the videos';
echo json_encode(getYoutubeVideos($Artist.' '.$Track, 1, 5, 'relevance'));
}
$.post('Videos.php', {
'action': 'getYoutubeVideos'
}, function(data) {
// do your stuff
}, 'json');
In your php code, do something like this:
$action = isset($_POST['action'])? $_POST['action'] : '';
if($action == 'getYoutubeVideos')
{
echo json_encode(getYoutubeVideos());
}
Then data in your JavaScript function will be the array/object/value returned by getYoutubeVideos().
I would do the JS part like ThiefMaster describes, but the php part would i handle a little bit different.
I would do something like this:
if(isset($_POST['action'], $_POST['par1'], $_POST['par2'])
{
$action = $_POST['action'];
$result = $this->$action($_POST['par1'], $_POST['par2]);
echo json_encode(result);
}
But be careful, if you have some methods in the class which shouldn't be called by the user, trough manipulating POST data, then you need some way to whitelist the methods the JavaScript may call. You can do it by prefixing the methods i.e:
$this->jsMethod.$action(....);
or by simple if/switch condition.
Ok here is what ended up working:
PHP CODE
$Action = isset($_POST['action']);
if($Action == 'getYoutubeVideos')
{
getYoutubeVideos($_POST['artist'].' '.$_POST['track'], 1, 5, 'relevance');
}
JQUERY
jQuery.ajax({
type: "POST",
url: "/Classes/Video.php",
data: "action=getYoutubeVideos&artist=artist&track=track",
success: function(data){
jQuery("#VideoPreview1").html(data);
}
});
json encoding was annoying, not sure if json is hte better way of doing it, I could actually use the jQuery.post function as well, because the real problem was with the PHP. If anyone knows about any security problems with the method I am doing, please let me know. Seems fine though.

Learning how to use AJAX with CodeIgniter

It's kind of embarassing that I find it so difficult to learn JavaScript, but ..
Let's say I have a really simple controller like this:
class front extends Controller {
public function __construct()
{
parent::Controller();
}
public function index()
{
//nothing!
}
public function test () {
$someNumber = $this->input->post('someNumber');
if ($someNumber == 12) { return TRUE; }
}
}
Yes, that could probably be written better, haha.
What I want to know is - how could I use JavaScript to submit a number in a form (I'll worry about validation and models later), how should I write my test() function so that it returns something readable by the JavaScript (I'm assuming return TRUE probably wouldn't work, perhaps XML or JSON or something like that?), and how do I access the data with the JavaScript?
I know there are frameworks like jQuery that will help with this, but right now I'd just like to understand it at the simplest level and all the tutorials and guides I've found so far are way too in depth for me. An example in jQuery or whatever would be good too.
Thanks a lot :)
you would just print it out basically, and re-capture that information via javascript:
public function test() {
$somenumber = $this->input->post('someNumber');
if ($somenumber == 12) {
print "Number is 12";
} else {
print "Number is not 12";
}
}
your javascript might look something like this:
var xhr;
xhr = new XMLHTTPRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
// this is where the return information is
alert('Status: '+xhr.status+' Response: '+xhr.responseText);
}
}
xhr.open('POST', '/front/test');
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send('someNumber=12');
the code above doesn't take into account browser specific issues, but should run on firefox/ie7 at least i believe.
here's a jQuery example of all the above:
var options = {
'someNumber' : 12
}
$.post('/front/test', options, function(data) {
alert(data); // should print "Number is 12"
});
I've also found in CodeIgniter that 'XMLHTTPRequest' isn't returned in the response headers, when using the standard Javascript AJAX call as mentioned above.
$this->input->is_ajax_request();
The input helper doesn't ever return true unless you use jQuery to handle the AJAX POST request.
I also tried the method in this article which didn't work: http://developer.practicalecommerce.com/articles/1810-The-Benefit-of-Putting-AJAX-and-CodeIgniter-PHP-Together
This is what I used in the end:
var query_params = $('#data-form').serialize();
$.ajax({
type: 'POST',
url: 'process_this.php",
data: queryParams,
context: document.body,
success: function(){
alert('complete'); // or whatever here
}
Possibly caused by a config issue to do with my CI install, haven't had time to investigate yet.

Categories