You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Drupal 9:通过AJAX加载的表单无法正常提交问题求助

解决Drupal表单AJAX动态加载后无法提交的问题

问题根源

直接通过jQuery AJAX获取并插入表单HTML时,Drupal表单的action属性生成的是临时表单路由令牌,且表单所需的Drupal JS行为未被正确绑定,导致提交失败。而直接访问Controller B时,Drupal完整请求流程会处理表单的路由、令牌和行为绑定,因此能正常提交。

最优解决方案:改用Drupal原生AJAX框架

Drupal自带的AJAX系统会自动处理表单的路由生成、行为绑定和提交逻辑,是最可靠的解决方式:

1. 修改Controller B的响应类型

将返回JSON改为返回Drupal的AJAX响应,让系统处理表单插入:

use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\ReplaceCommand;

public function get_form() {
  $form = \Drupal::formBuilder()->getForm('Drupal\my_module\Form\MyForm');
  $response = new AjaxResponse();
  // 用表单内容替换#form容器
  $response->addCommand(new ReplaceCommand('#form', $form));
  return $response;
}

2. 调整前端实现(两种可选方式)

方式一:使用Drupal.ajax API替代纯jQuery AJAX

$('#ajax-link').on('click', function(e) {
  e.preventDefault();
  // 初始化Drupal AJAX对象
  const ajax = Drupal.ajax({
    url: '/controller-B/get-form',
    wrapper: 'form', // 目标容器ID
    method: 'replace',
    progress: { type: 'throbber' } // 加载动画
  });
  ajax.execute();
});

方式二:使用Drupal内置AJAX链接(无需自定义JS)

直接在Controller A的输出中使用带AJAX属性的链接:

<a id="ajax-link" href="/controller-B/get-form" class="use-ajax" data-use-ajax-wrapper="form">Click here to display the form</a>
<div id="form"></div>

注:确保页面已加载core/drupal.ajax库(默认Drupal会加载,自定义页面需手动引入)。

备选方案:纯jQuery AJAX兼容处理

若必须保留纯jQuery AJAX实现,需补充两个关键步骤:

1. 手动设置表单action路径

在Controller B中明确指定表单提交路径,避免生成临时令牌路径:

public function get_form() {
  $form = \Drupal::formBuilder()->getForm('Drupal\my_module\Form\MyForm');
  // 替换为你的表单提交路由
  $form['#action'] = \Drupal\Core\Url::fromRoute('my_module.form_submit')->toString();
  $output = \Drupal::service('renderer')->render($form);
  $data = new \StdClass();
  $data->output = $output;
  return new JsonResponse($data);
}

2. 插入表单后绑定Drupal行为

在JS的success回调中调用Drupal.attachBehaviors(),触发表单JS行为绑定:

$("#ajax-link").on("click", function() {
   $.ajax({
     url: "/controller-B/get-form",
     type: "POST",
     dataType: "JSON",
     success: function(data) {
        $("#form").html(data.output);
        // 绑定Drupal表单行为
        Drupal.attachBehaviors("#form");
     }
});

关键说明

  • 备选方案不推荐:手动处理action和行为绑定可能遗漏Drupal表单的安全验证(如CSRF令牌),长期维护性差。
  • 确保表单类MyForm正确实现getFormId()、buildForm()、submitForm()方法,且提交路由已在routing.yml中正确配置。

内容的提问来源于stack exchange,提问作者Hubert

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 05:39:54