I'm using Joomla for a project, and there's some Ajax requests happening to populate data. I generate a Joomla session token in the PHP view, and tack this onto the URL of the Ajax request endpoint, which is also a PHP page, and validates the token before returning data.
Something like this:
// view.html.php
$script = "var ajaxurl = 'index.php?task=ajaxFunction&".JFactory::getSession()->getFormToken()."=1';";
$document->addScriptDeclaration($script);
// ajax.js
var request = new Request.JSON({
url: ajaxurl,
onException: function(headerName, value) {
// etc.
}
});
// controller
public function ajaxfunction()
{
JRequest::checkToken('get') or die( 'Invalid Token!' );
// do other stuff
}
This works just fine until caching is enabled.
The problem is that the view.html.php file, when Joomla uses its internal caching, is cached with the token already set-- so anytime a browser requests the page, it pulls the cached token along with it, meaning the controller will return an invalid Token error.
I know in earlier Joomla builds caching flat out didn't work. Is there a way to make this work in Joomla 2.5+, short of just disabling the Joomla cache? I can't find any way to exclude a single view from caching.
Perhaps you may want to send the request as POST instead of GET, which won't use Joomla caching.
ajax.js
var userToken = document.getElementsByTagName("input")[0].name;
var request = new Request.JSON({
url: 'index.php?task=ajaxFunction&'+ userToken +'=1',
onException: function(headerName, value) {
// etc.
}
onComplete: function(res) {
// etc.
}
}).post({});
controller
JRequest::checkToken('get') or die( 'Invalid Token!' );
Stick this at the top of your template file (before all other input tags), it will create a hidden input field containing a token, which will eventually be replaced with the non-cached one on render
tmpl/default.php
<?= JHtml::_('form.token'); ?>
Sometimes I work with Ajax and Joomla and really do not have this problem. Well, maybe the way you is working, is maybe better try a diferent way of do the cache, so if you really have no hope , just fork System - Cache from Joomla, and on your fork make it does not cache what you do not want. If in your project is possible to handle how you do your cache, you can also do not use Joomla Cache and use it with Varnish or similar.
I think it should be better than how you're doing: Joomla have one group to include one more "standard" way to work with AJAX, and you can see one Proof of Concept Here:
https://github.com/betweenbrain/Joomla-Ajax-Interface
Discussion here
https://groups.google.com/d/msg/joomla-dev-general/i1syYWshGsY/3udixCaRnRAJ
Also, another aproach about use of Ajax is here
https://github.com/juliopontes/joomla-ajax-handle
By looking at the method signature of JSession::getFormToken() you should be able to force a new token by calling getFormToken(true).
This should circumvent any caching issues you're experiencing.
The way I do it in joomla with a very similar set up is inject the value with JavaScript. The page is cached without the token and JavaScript adds it before making the request
You can pass the value with cookies or another ajax request. Cookies works best fort me
Related
I am new to Magento currently I am trying to make a regular Ajax call from my JS file. To a PHP file located in a root of my project same level as app folder. However when I execute the call ajax part works fine however I always get 500 response in my network console. If I try to call file directly like website.com/file.php it shows nothing but it should. Is there something in magento that is preventing me from doing this?
Also what is the best way to set a session and cookie in Magento, I did a small script locally that once pop up is closed it doesn't show it for the remainder of the session (and it works locally) but in Magento I can't get it.
Here is some of my code:
Ajax
// Create a session to not show pop-up
jQuery.ajax({
url: jQuery('#baseURL').val() + "/mailchimp_controls.php",
type: "post",
data: { "action": "session" },
success: function(data){
// Do something if necessary
}
});
PHP
// If Session set a session
if($_POST['action'] == "session"){
return "Session";
// Set value in session
$seen = true;
//Mage::getSingleton('core/session')->setShowMailChimp($seen);
}
I managed to solve this, I have create a Magento Module inside the APP/Core/Local
Where I was able to use MAGE to set sessions and cookies, if anyone is experiencing similar issues I would Google a tutorial on how to create a module inside (local) folder so that it is not overridden when you upgrade.
(repost from https://groups.google.com/forum/?hl=en&fromgroups=#!topic/hybridauth/CWo2R9suYts)
Starting with Facebook, I'm trying to use the provider Javascript SDKs to login and have HybridAuth "know" about it. Any help would be appreciated.
I started by including the configuration IDs in the data I pass to the View so I can use them when calling Javascript login functions. So in the middle of the GetProviders function of the Hybrid_Auth class, I added:
if(array_key_exists('keys', $params) && array_key_exists('id', $params['keys']))
$idps[$idpid]['id'] = $params['keys']['id'];
My Javascript includes something like this:
FB.init({
appId:'<?php echo $providers['Facebook']['id']; ?>',
cookie:true,
status : true,
xfbml:true
});
So far so good.
But after logging in (i.e., FB.login()) of course HybridAuth doesn't know and doesn't have the user information.
Then to "force" it, I tried calling the ".../hauth/login/Facebook" method via Ajax:
$.ajax({
type: "POST",
url: ".../hauth/login/Facebook",
cache: false,
...
Unfortunately, it seems like a number of 'redirects' in HybridAuth make this not work. I even added "data: {ajax:true}," to the Ajax call and tried to modify HyrbidAuth to not redirect if it $_POST['ajax'] existed. That didn't seem to do it either. (I even removed the "die();" at the end of the redirect() function to no avail.)
I'm thinking I'm either on the right track or I need to add a new HybridAuth method to detect and store data for all or specific connections that already exist.
Any ideas?
Thanks.
I attempted several ways to login to a Provider using a Javascript SDK and integrate that with HyrbidAuth. No solution was very pretty, and each required that I alter HybridAuth which would be difficult to maintain. I finally determined that the best solution was to follow the "widget" example included with HybridAuth.
I didn't use the widget, but the code shows a method for opening and closing a separate smaller window using Javascript. That window's URL contains information for the server to call HybridAuth's 'authenticate' method which redirects to the Provider's login/approval page.
The effect is essentially the same: the user stays on the same page while authenticating with a Provider in a separate "window."
I am having problems with this topic: Access-Control-Allow-Origin.
I read about it and I found that is possible to get response using php, here
But I don't know how to adapt that code to javascript, I still have the same problem.
I tried this in javascript:
var url ='http://localhost:8080/com.webserver/rest/manage/order?parameter=parameter';
req=Ajax("getResponse.php/?" + url)
if (req.status=200)
alert("hi");
And on php file:
<?php
echo file_get_contents($_GET['url']);
?>
And nothing happends. I tried with ajax, something like:
$.ajax({
url: "http://localhost:8080/com.webserver/rest/manage/order?parameter=parameter",
async: false,
dataType: 'html',
success: function (text) {
alert(text);
}
});
But always same problem....
I read lot of people on internet having the same problem, but no one get a response. I just found 2 ways, using chrome and one option but just recomended for developers and adding headers on server but I don't know where to add them. I am using apache tomcat catalina for that localhost. I have 2 servers, webpage (in xampp) and rest (in tomcat)
Change
req=Ajax("getResponse.php/?" + url)
to
req=Ajax("getResponse.php/?url=" + url)
Bare in mind this is insecure, i could pass anything into the url parameter and your php scripts would use it. Allowing people to read files from your local system as well as get your php script to download malicious files from elsewhere
Edit:
To best way to secure it is to use an actions list, this means that the user never see's the url and can only modify an action word. for example
req=Ajax("getResponse.php/?do=getOrders")
then in php
$actions = array();
$actions['getOrders'] = "http://localhost:8080/com.webserver/rest/manage/order?parameter=parameter";
if(array_key_exists($_GET['do'], $actions))
echo file_get_contents($actions[$_GET['do']]);
Usually you'd want to do more that just translate an action to a url, you may want to pass additional parameters. In this case you could use a switch or a bunch of IF's to check if $_GET['do'] is equal to something and then process it. but it would take hours to give an example of every possible implementation method, so you may want to use google.
Please note: whilst this method is suggest adds 100x more security to your script, its not infallable, especially if you start passing through parameters from users too. Once again use google.
Is it possible to set PHP session variables using Javascript?
In JavaScript:
jQuery('#div_session_write').load('session_write.php?session_name=new_value');
In session_write.php file:
<?
session_start();
if (isset($_GET['session_name'])) {$_SESSION['session_name'] = $_GET['session_name'];}
?>
In HTML:
<div id='div_session_write'> </div>
The session is stored server-side so you cannot add values to it from JavaScript. All that you get client-side is the session cookie which contains an id. One possibility would be to send an AJAX request to a server-side script which would set the session variable. Example with jQuery's .post() method:
$.post('/setsessionvariable.php', { name: 'value' });
You should, of course, be cautious about exposing such script.
If you want to allow client-side manipulation of persistent data, then it's best to just use cookies. That's what cookies were designed for.
or by pure js, see also on StackOverflow :
JavaScript post request like a form submit
BUT WHY try to set $_session with js? any JS variable can be modified by a player with
some 3rd party tools (firebug), thus any player can mod the $_session[]! And PHP cant give js any secret codes (or even [rolling] encrypted) to return, it is all visible. Jquery or AJAX can't help, it's all js in the end.
This happens in online game design a lot. (Maybe a bit of Game Theory? forgive me, I have a masters and love to put theory to use :) ) Like in crimegameonline.com, I
initialize a minigame puzzle with PHP, saving the initial board in $_SESSION['foo'].
Then, I use php to [make html that] shows the initial puzzle start. Then, js takes over, watching buttons and modding element xy's as players make moves. I DONT want to play client-server (like WOW) and ask the server 'hey, my player want's to move to xy, what should I do?'. It's a lot of bandwidth, I don't want the server that involved.
And I can just send POSTs each time the player makes an error (or dies). The player can block outgoing POSTs (and alter local JS vars to make it forget the out count) or simply modify outgoing POST data. YES, people will do this, especially if real money is involved.
If the game is small, you could send post updates EACH move (button click), 1-way, with post vars of the last TWO moves. Then, the server sanity checks last and cats new in a $_SESSION['allMoves']. If the game is massive, you could just send a 'halfway' update of all preceeding moves, and see if it matches in the final update's list.
Then, after a js thinks we have a win, add or mod a button to change pages:
document.getElementById('but1').onclick=Function("leave()");
...
function leave() {
var line='crimegameonline-p9b.php';
top.location.href=line;
}
Then the new page's PHP looks at $_SESSION['init'] and plays thru each of the
$_SESSION['allMoves'] to see if it is really a winner. The server (PHP) must decide if it is really a winner, not the client (js).
You can't directly manipulate a session value from Javascript - they only exist on the server.
You could let your Javascript get and set values in the session by using AJAX calls though.
See also
Javascript and session variables
jQuery click event to change php session variable
One simple way to set session variable is by sending request to another PHP file. Here no need to use Jquery or any other library.
Consider I have index.php file where I am creating SESSION variable (say $_SESSION['v']=0) if SESSION is not created otherwise I will load other file.
Code is like this:
session_start();
if(!isset($_SESSION['v']))
{
$_SESSION['v']=0;
}
else
{
header("Location:connect.php");
}
Now in count.html I want to set this session variable to 1.
Content in count.html
function doneHandler(result) {
window.location="setSession.php";
}
In count.html javascript part, send a request to another PHP file (say setSession.php) where i can have access to session variable.
So in setSession.php will write
session_start();
$_SESSION['v']=1;
header('Location:index.php');
Not possible. Because JavaScript is client-side and session is server-side. To do anything related to a PHP session, you have to go to the server.
be careful when doing this, as it is a security risk. attackers could just repeatedly inject data into session variables, which is data stored on the server. this opens you to someone overloading your server with junk session data.
here's an example of code that you wouldn't want to do..
<input type="hidden" value="..." name="putIntoSession">
..
<?php
$_SESSION["somekey"] = $_POST["putIntoSession"]
?>
Now an attacker can just change the value of putIntoSession and submit the form a billion times. Boom!
If you take the approach of creating an AJAX service to do this, you'll want to make sure you enforce security to make sure repeated requests can't be made, that you're truncating the received value, and doing some basic data validation.
I solved this question using Ajax. What I do is make an ajax call to a PHP page where the value that passes will be saved in session.
The example that I am going to show you, what I do is that when you change the value of the number of items to show in a datatable, that value is saved in session.
$('#table-campus').on( 'length.dt', function ( e, settings, len ) {
$.ajax ({
data: {"numElems": len},
url: '../../Utiles/GuardarNumElems.php',
type: 'post'
});
});
And the GuardarNumElems.php is as following:
<?php
session_start();
if(isset ($_POST['numElems'] )){
$numElems = $_POST['numElems'];
$_SESSION['elems_table'] = $numElems;
}else{
$_SESSION['elems_table'] = 25;
}
?>
Help, if you can-
The situation:
http://foobar.com includes a remotely hosted javacript file (http://boobar.com/stuff.js).
The goal is to just get an alert from the remotely hosted php script on foobar.com
I have tried the following code in stuff.js:
$.ajax({
type: "GET",
url: "http://www.boobar.com/script.php?callback=?",
dataType: 'jsonp',
success: function(result) { alert(result); }
});
No luck.
$.getJSON("http://www.boobar.com/script.php?jsonp=?",
function(data) { alert(data); }
);
Also no luck.
On the php side I have tried both the following:
return json_encode(array(0 => 'test'));
echo json_encode(array(0 => 'test'));
In Firefox I get a security error. I understand that it thinks I'm violating the security model. However, according to the jquery documentation, I should be able to accomplish this.
The error seems to be a security feature of the Same Origin Policy: to simplify, you can only make AJAX requests for stuff on the originating server (http://foobar.com). One way around this is to make a simple facade on the originating server, e.g.:
<?php
// this file resides at http://foobar.com/getstuff.php
echo file_get_contents('http://www.boobar.com/script.php?callback=?'
. $possibly_some_other_GET_parameters );
?>
Then, from foobar.com, you can make an AJAX request for http://foobar.com/getstuff.php (which in turn makes a HTTP GET request from your web server to boobar.com and sends it back to the browser).
To the browser, the request goes to the origin server, and is allowed (the browser has no way of knowing that the response comes from somewhere else behind the scene).
Caveats:
the PHP config at foobar.com must have allow_url_fopen set to "1". Although this is the default setting, some servers have it disabled.
the request to www.boobar.com is made from foobar.com server, not from the browser. That means no cookies or user authentication data are sent to www.boobar.com, just whatever you put into the request URL ("$possibly_some_other_GET_parameters").
You can get data from another server asynchronously using script tags and json:
<script type="text/javascript" src="http://somesite.com/path/to/page/"></script>
You can use this to dynamically load a remote javascript (by created a new script element and setting the src attribute, then loading into the DOM), which could set a variable. However, you need to really trust the remote site, because the JS will be evaluated without any precondition.
There is a method called window.name transport or window.name method which uses a general browser bug(not sure if this is a bug actually). You make the request through an iFrame and the loaded page puts the information you need to the "name" property of the JavaScript window object of itself.
This method uses a "blank.htm" since it first navigates to the target page and then goes back to the blank.htm page to overcome the "same origin policy" restriction.
Dojo have implemented this and you can find a more detailed explanation here.
Also I have implemented a cross-domain XMLHttpRequest object based on this method in the library I have written which can be found here.
You may not be able to use the library since it will need 1 or 2 additional libraries which can be found here.
If you need further help in implementing it in your style, I'll try to do my best.
So what I ended up doing, since it was just a GET - no data need to be retrieved - I used JQuery to create a hidden iframe with the URL including the variables I wanted to pass set as the source. Worked like a charm. To all who provded feedback - Thanks!
How about this !! Using a php proxy.
Cross-Domain AJAX calls using PHP
http://www.phpfour.com/blog/2008/03/cross-domain-ajax-using-php/
jQuery .ajax also has a setting 'crossDomain'.
http://api.jquery.com/jQuery.ajax/
crossDomain (default: false for same-domain requests, true for cross-domain requests)
Type: Boolean
If you wish to force a crossDomain request (such as JSONP) on the same domain, set the value of crossDomain to true. This allows, for example, server-side redirection to another domain. (version added: 1.5)