我在一个项目中使用Joomla,其中发生了一些Ajax请求来填充数据。我在PHP视图中生成一个Joomla会话令牌,并将其附加到Ajax请求端点的URL(也是一个PHP页面),并在返回数据之前验证令牌。
像这样:
// 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
}
在启用缓存之前,这个工作正常。
问题是view.html.php
文件,当Joomla使用其内部缓存时,是与已经设置的令牌一起缓存的——所以每当浏览器请求页面时,它都会将缓存的令牌与它一起拉,这意味着控制器将返回一个无效的令牌错误。
我知道在早期的Joomla构建中,缓存完全不起作用。在Joomla 2.5+中,除了禁用Joomla缓存之外,有没有办法让这个工作?我找不到任何方法来从缓存中排除单个视图
也许您想以POST而不是GET的方式发送请求,这将不使用Joomla缓存。
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({});
控制器JRequest::checkToken('get') or die( 'Invalid Token!' );
把它放在模板文件的顶部(在所有其他输入标签之前),它将创建一个包含令牌的隐藏输入字段,该字段最终将在渲染
时被未缓存的令牌所替换。/tmpl default.php
<?= JHtml::_('form.token'); ?>
有时我使用Ajax和Joomla,真的没有这个问题。好吧,也许你的工作方式,也许是更好的尝试不同的方式做缓存,所以如果你真的没有希望,只需从Joomla分叉System - cache ,并在你的分叉使它不缓存你不想要的东西。如果在你的项目中有可能处理你如何做你的缓存,你也可以不使用Joomla缓存和使用Varnish或类似的。
我认为它应该比你现在做的更好:Joomla有一个小组,包括一个"标准"的方式来使用AJAX,你可以在这里看到一个概念证明:
- https://github.com/betweenbrain/Joomla-Ajax-Interface
- https://groups.google.com/d/msg/joomla-dev-general/i1syYWshGsY/3udixCaRnRAJ
另外,关于使用Ajax的另一种方法在这里
- https://github.com/juliopontes/joomla-ajax-handle
通过查看JSession::getFormToken()
的方法签名,您应该能够通过调用getFormToken(true)
来强制生成新的令牌。
我在joomla中使用非常类似的设置的方法是用JavaScript注入值。缓存的页面没有令牌,JavaScript在请求
之前添加它。您可以通过cookie或其他ajax请求传递该值。