首页 > 解决方案 > 表单提交完成后的 JavaScript 调用函数

问题描述

我有一个使用 jquery 插件创建的隐藏表单,我需要在提交发生后运行一个函数,但它似乎没有被调用。表单发布后,我需要获取新的 csrf 详细信息。

提交表单后我想获取新生成的csrf详细信息

$(this).on('click', function() {
    $('#' + settings.title.replace(/\s+/g, '-').toLowerCase() + '-export-csv').submit();
    get_csrf_details();
});

与将在插件中使用的 export-csv 类和数据的 Html 链接。使用 smarty 模板。

<a href="#" class="export-csv" data-title='Landlords' data-data='{base64_encode($landlords_json)}'>
    Export (CSV)
</a>

导出CSV插件

(function($) {

    $.fn.exportCSV = function ( options ) {

        return $(this).each(function() {
            var settings = $.extend({
                title: null,
                data: null,
                link: '/',
            }, options);

            settings.title = $(this).data('title');
            settings.data = $(this).data('data');

            var hidden_form = "<form id='" + settings.title.replace(/\s+/g, '-').toLowerCase() + "-export-csv' action='" + settings.link + "' method='POST' style='display: none;'>" +
                    "<input type='hidden' class='csrf_field' name='" + csrfName + "' value='" + csrfHash + "'>" +
                    "<input type='hidden' name='title' value='" + settings.title + "'>" +
                    "<input type='hidden' name='data' value='" + settings.data + "'>" +
                "</form>";
            $(this).append(hidden_form);

            $(this).on('click', function() {
                $('#' + settings.title.replace(/\s+/g, '-').toLowerCase() + '-export-csv').submit();
                get_csrf_details();
            });
        });
    }
}(jQuery));

$(".export-csv").exportCSV({
    link: '/dashboard/export-csv'
});

// 从服务器获取 csrf 详细信息

var get_csrf_details = function get_csrf_details() {
    $.get('/ajax/get-csrf-details', function(response) {
        var csrfName = response.data.csrf.name;
        var csrfHash = response.data.csrf.hash;

        // const csrf_input1 = document.querySelector('.csrf_field');
        const csrf_inputs = document.getElementsByClassName('csrf_field');

        for (i = 0; i < csrf_inputs.length; i++) {
            csrf_inputs[i].name = csrfName;
            csrf_inputs[i].value = csrfHash;
        }
    });
};

标签: javascriptjquery

解决方案


无法知道<form>元素的提交何时成功完成。

但是,鉴于您正在做的事情,只使用 AJAX 会更有意义。这意味着您可以控制收到响应时执行的确切逻辑,并且不必注入隐藏表单和伪造提交,这远非理想。尝试这个:

$.fn.exportCSV = function(options) {
  return $(this).each(function() {
    var settings = $.extend({
      title: null,
      data: null,
      link: '/',
    }, options);

    settings.title = $(this).data('title');
    settings.data = $(this).data('data');

    $(this).on('click', function() {
      var data = {
        title: settings.title,
        data: settings.data
      };
      data[csrfName] = csrfHash;

      $.ajax({
        url: settings.link,
        type: 'POST',
        data: data,
        success: function(response) {
          // the submission has been made, perform required logic here. 
          get_csrf_details();
        },
        error: function() {
          // something went wrong, debug it!
        }
      });
    });
  });
}

有几点需要注意。首先,在第一个请求的响应中返回新的 CSRF 可能更有意义。这将节省您的网络流量。

其次,您总是在设置settings.titlesettings.data匹配data定义此函数的元素上的属性,因此使用settings对象是毫无意义的,因为它总是会被覆盖,即使没有data提供任何属性。您可以改为修改逻辑以仅在data它们存在时使用。


推荐阅读