Drupal Ajax:通过URL传递值 vs 数据参数

3

使用以下两种方式有什么区别:

 $.ajax({
  type: 'POST',
  url: Drupal.settings.basePath + 'module/get/' + node,
  dataType: 'json',
  data: { 'ajax' : true }
 });

对比:

 $.ajax({
  type: 'POST',
  url: Drupal.settings.basePath + 'module/get',
  dataType: 'json',
  data: { 'ajax' : true, 'node' : node }
 });

在第一种情况下,您将在回调函数中将节点变量作为参数访问,在第二种情况下,您将使用$ _POST ['node']进行访问,对吗?第二种方法总是更好,但我看到很多人都是用第一种方法。并不是说第二种方式更安全。仍在研究表单令牌,但首先要弄清楚这个基本点。
另外,对于情况1,假设此ajax由按钮触发,如何阻止人们直接输入网址mysite/module/get/20并激活它?只需检查$ _POST ['ajax'] == true是否足以解决这个问题?还是那里仍然存在安全漏洞?

你能解释一下为什么你认为第二种方法总是更好吗? - marcvangend
我曾认为这种方式会更好,因为它不会在URL中暴露参数。现在我明白了两种方式都很有用。 - Wade
1个回答

4

乍一看没有实际区别:

假设您的“node”变量只是一个节点id,那么两者之间没有太大区别。从语义上讲,它们似乎都执行了“获取”操作(尽管它们在技术上是post请求),因为它们仅检索数据而不更改服务器上的任何状态(好吧,这是另一个假设)。

就安全性而言,也没有相关差异-两者都可以轻松“伪造”,区别仅在于与“标准”GET vs. POST辩论相同,即除了第一个将参数稍微更加“可访问”外,因为它们在URL中是明文显示的。

但在Drupal中有一个“方便”的差异:

在Drupal中,经常遇到第一个版本,因为它可以利用Drupal 6中引入的通配符加载器参数功能。假设您的回调URL在hook_menu中定义如下:

$items['module/get/%node'] = array(
'title' => 'Foo',
'type' => MENU_CALLBACK,
'page callback' => 'yourModule_callback',
'page arguments' => array(2),
);

通过这样做,当传入nid时,yourModule_callback()将被调用,它的第一个参数已经是完全加载的节点对象,因为%node告诉Drupal在将参数交给回调函数之前执行node_load()。使用你示例的第二个版本,回调函数必须自己加载节点对象,从POST数据中提取它后。

所以这里是一种方便的方式。

此外,在Drupal中常见的模式是在AJAX请求和非JavaScript“回退”替代方案中使用相同的回调URL。因此,当调用yourModule_callback()时,它首先可以对传入的节点执行其预期操作,基本上组装其结果。完成后,它只检查POST数据中是否有$ajax == TRUE。如果有,它知道结果是针对AJAX请求的,因此可能将结果输出为JSON。如果没有,它知道正在进行完整的页面循环,并可以相应地调整其输出(例如重新构建表单、重新生成整个页面等)。

这样,您不必为您的非AJAX / AJAX回调注册单独的URL。


感谢您详细解释了这两者之间的区别。:) 现在我明白了两种方法都可以很有用。我的表单工作方式通常是为 ajax 设计的,但如果 js 被禁用,它将回退到使用表单 API 提交表单。 - Wade
你是否还在犹豫,是否可以仅通过检查$ajax==TRUE来确定某人是否只是转到了URL而不是使用表单,这样就可以确保不会触发回调函数。例如,最初您转到“mysite/module/get/20”,并将触发回调(我不希望发生),但如果您包装回调并检查$ajax==true,则可以防止发生这种情况。因此,该URL将不再触发回调,并且也无法使用类似mysite/module/get/20&ajax=true的内容来触发回调?是否仍有巧妙的方法可以绕过它,或者应该是安全的?谢谢。 - Wade
它并不是“万无一失”的。它只能确认“ajax = true”已经被提交给你,但不能确认这个提交实际上来自你的表单。(因此只能防止通过标准GET方式进行“简单”的访问)。为了确保提交本身来自表单,您必须使用formsAPI处理逻辑重建表单并验证表单令牌。对于一个简单的AJAX回调来说,这听起来有点过度 - 为什么您要担心某人可以在没有来自表单的情况下获取数据?(如果用户可以访问表单,他可以随时获取AJAX响应) - Henrik Opel
对于这个ajax,我不太担心,但我还有另一个ajax表单,它将数据插入数据库。我刚刚在我的表单中添加了一个额外的令牌,但我不确定它是否与您提到的那种相同。我使用drupal_get_token将其添加到drupal.settings并将其作为数据发送,并使用drupal_valid_token在服务器端进行验证。这是为了防止XSS,而您所说的令牌是不同的,对吗?我该如何使用那种方法?也许那也可以帮助解决我的另一个问题:http://stackoverflow.com/questions/2130714/drupal-6-validation-for-form-callback-function - Wade
这是表单 API 使用的相同令牌机制。我在您的另一个问题中发布了答案 - 那里的链接应该会有所帮助。(很抱歉没有提供具体示例,但我不记得细节,总是需要在几个月后再次查找这些内容 ;) - Henrik Opel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接