【问题标题】:How can I intercept a JavaScript-triggered form submission?如何拦截 JavaScript 触发的表单提交?
【发布时间】:2019-08-03 06:36:44
【问题描述】:

有没有办法拦截由 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 的表单提交是垃圾邮件机器人用来提交表单的方法 - 这表明表单垃圾邮件并未通过这些努力减少。他们能够绕过我的检查。

需要明确的是,第三方表单服务在实际的字段验证服务器端完成了繁重的工作。我只是想首先减少发送到他们服务器的垃圾邮件数量。

是否可以拦截这个基于 JavaScript 的表单提交?我是不是用错误的方式处理这个问题?

编辑:为了澄清,onsubmit 方法确实在通过表单的提交按钮提交表单时被调用。但是当通过 JavaScript (.submit()) 提交表单时它不会被调用。

【问题讨论】:

标签: javascript jquery forms spam spam-prevention


【解决方案1】:

仅在前端检查 reCAPTCHA 没有任何作用,也绝不是安全预防措施。客户端可以换出/完全忽略您的 javascript。 Please check the validity of the request backend-side.

但是,如果您想拦截请求,可以使用 Service Worker。考虑到

,减少服务器上的负载
  1. 机器人 UserAgent 使用此功能。
  2. 机器人实际上会呈现您的前端以发送请求
  3. 您的网站使用 https

Service Worker 充当客户端、服务器和缓存之间的代理。因此,它可以检查和修改客户端发送的请求。在这种情况下,我们要检查请求中是否存在某个属性,如果找不到则忽略该请求。

&lt;form ... action="/my-form-route" id="my_form" onSubmit="submitHandler()"&gt;

main.js

if ('serviceWorker' in navigator) {
  navigator.serviceWorker.register('/service-worker.js');
}

service-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": "jeff@totallylegit.com", "content": "WOW NICE ARTICLE\n free leg enlargement @ totallylegit.com btw lol"}' \
  http://example.com/my-form-route

【讨论】:

  • 感谢您的信息。在这种情况下,我将研究 Service Worker 是否是一个不错的选择。
  • 当然可以。玩得开心!
猜你喜欢
  • 2012-04-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-26
  • 2011-07-20
  • 2013-01-30
相关资源
最近更新 更多