拦截 JavaScript 中的表单提交并阻止正常提交

似乎有很多关于如何使用 javascript 提交表单的信息,但我正在寻找一个解决方案,以便在表单提交后捕获并在 javascript 中拦截它。

超文本标示语言

<form>
<input type="text" name="in" value="some data" />
<button type="submit">Go</button>
</form>

当用户按下提交按钮时,我确实希望提交表单,但是我希望调用一个 JavaScript 函数。

function captureForm() {
// do some stuff with the values in the form
// stop form from being submitted
}

一个快速的方法是在按钮上添加一个 onclick 函数,但是我不喜欢这个解决方案... 提交表单的方法有很多... 例如,在输入时按回车键,这并没有考虑到这一点。

186724 次浏览

<form onSubmit="return captureForm()"> that should do. Make sure that your captureForm() method returns false.

<form id="my-form">
<input type="text" name="in" value="some data" />
<button type="submit">Go</button>
</form>

In JS:

function processForm(e) {
if (e.preventDefault) e.preventDefault();


/* do what you want with the form */


// You must return false to prevent the default form behavior
return false;
}


var form = document.getElementById('my-form');
if (form.attachEvent) {
form.attachEvent("submit", processForm);
} else {
form.addEventListener("submit", processForm);
}

Edit: in my opinion, this approach is better than setting the onSubmit attribute on the form since it maintains separation of mark-up and functionality. But that's just my two cents.

Edit2: Updated my example to include preventDefault()

Use @Kristian Antonsen's answer, or you can use:

$('button').click(function() {
preventDefault();
captureForm();
});

You cannot attach events before the elements you attach them to has loaded

It is recommended to use eventListeners - here one when the page loads and another when the form is submitted

This works since IE9:

Plain/Vanilla JS

// Should only be triggered on first page load
console.log('ho');


window.addEventListener("DOMContentLoaded", function() {
document.getElementById('my-form').addEventListener("submit", function(e) {
e.preventDefault(); // before the code
/* do what you want with the form */


// Should be triggered on form submit
console.log('hi');
})
});
<form id="my-form">
<input type="text" name="in" value="some data" />
<button type="submit">Go</button>
</form>

jQuery

// Should only be triggered on first page load
console.log('ho');


$(function() {
$('#my-form').on("submit", function(e) {
e.preventDefault(); // cancel the actual submit


/* do what you want with the form */


// Should be triggered on form submit


console.log('hi');
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<form id="my-form">
<input type="text" name="in" value="some data" />
<button type="submit">Go</button>
</form>

Not recommended but will work

If you do not need more than one event handler, you can use onload and onsubmit

// Should only be triggered on first page load
console.log('ho');


window.onload = function() {
document.getElementById('my-form').onsubmit = function() {
/* do what you want with the form */


// Should be triggered on form submit
console.log('hi');
// You must return false to prevent the default form behavior
return false;
}
}
    <form id="my-form">
<input type="text" name="in" value="some data" />
<button type="submit">Go</button>
</form>

Another option to handle all requests I used in my practice for cases when onload can't help is to handle javascript submit, html submit, ajax requests. These code should be added in the top of body element to create listener before any form rendered and submitted.

In example I set hidden field to any form on page on its submission even if it happens before page load.

//Handles jquery, dojo, etc. ajax requests
(function (send) {
var token = $("meta[name='_csrf']").attr("content");
var header = $("meta[name='_csrf_header']").attr("content");
XMLHttpRequest.prototype.send = function (data) {
if (isNotEmptyString(token) && isNotEmptyString(header)) {
this.setRequestHeader(header, token);
}
send.call(this, data);
};
})(XMLHttpRequest.prototype.send);




//Handles javascript submit
(function (submit) {
HTMLFormElement.prototype.submit = function (data) {
var token = $("meta[name='_csrf']").attr("content");
var paramName = $("meta[name='_csrf_parameterName']").attr("content");
$('<input>').attr({
type: 'hidden',
name: paramName,
value: token
}).appendTo(this);


submit.call(this, data);
};
})(HTMLFormElement.prototype.submit);




//Handles html submit
document.body.addEventListener('submit', function (event) {
var token = $("meta[name='_csrf']").attr("content");
var paramName = $("meta[name='_csrf_parameterName']").attr("content");
$('<input>').attr({
type: 'hidden',
name: paramName,
value: token
}).appendTo(event.target);
}, false);