有没有办法拦截由JavaScript触发的表单提交?
我试图通过执行一些客户端验证来减少来自机器人的垃圾邮件提交(如果重要的话,在reCAPTCHA v2的帮助下)。当用户提交表单时,我可以通过检查通过表单的onSubmit属性指定的方法中的标志来确认输入数据已经过验证(reCAPTCHA已经填写)...
<form ... id="my_form" onSubmit="submitHandler()">
function submitHandler(e) {
if ( !valid ) {
e.preventDefault();
}
}
...或者通过jQuery .submit()事件处理程序定义的方法:
$('#my_form').submit(function(e) {
if ( !valid ) {
e.preventDefault();
}
});
问题是,当通过JavaScript提交表单时,这些方法似乎都不会被调用。当我打开控制台并测试通过JavaScript提交时......
document.getElementById('my_form').submit()
...表单提交,两种方法都没有被调用。表单提交事件似乎没有被触发,因此我无法检查数据是否已经过验证。
据推测,这个基于JavaScript的表单提交是spambots用于提交表单的方法 - 跟踪表单垃圾邮件尚未通过这些努力减少的事实。他们能够绕过我的支票。
需要明确的是,第三方表单服务可以在服务器端的实际现场验证中完成。我只是想减少首先发送到他们服务器的垃圾邮件数量。
是否有可能拦截这个基于JavaScript的表单提交?我是以错误的方式接近这个吗?
编辑:为了澄清,当通过表单的提交按钮提交表单时,会调用onsubmit方法。但是当通过JavaScript(.submit())提交表单时,它不会被调用。
只检查前端的reCAPTCHA什么都不做,绝不是安全预防措施。客户端可以换出/完全忽略您的JavaScript。 Please check the validity of the request backend-side。
但是,如果你想要e.gG,可以使用Service Worker拦截请求。鉴于此,减少服务器上的负载
服务工作者充当客户端,服务器和缓存之间的代理。因此,它可以检查和修改客户端发送的请求。在这种情况下,我们要检查请求中是否存在某个属性,如果找不到请求,则忽略该请求。
<form ... action="/my-form-route" id="my_form" onSubmit="submitHandler()">
main.js
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/service-worker.js');
}
服务worker.js
self.addEventListener('fetch', (event) => {
// use json(), text() or formData() depending on what the request should look like
const formData = await event.request.body.formData();
if (event.request.url.includes('my-form-route') && formData.valid) {
return; // if google recaptcha is found in request object, ignore the request
}
event.respondWith(
new Promise (resolve, reject) {
reject('nope')
}
)
})
这可以很容易地绕过:
curl --header "Content-Type: application/json" \
--request POST \
--data '{"username":"Jeff","email": "[email protected]", "content": "WOW NICE ARTICLE\n free leg enlargement @ totallylegit.com btw lol"}' \
http://example.com/my-form-route