JavaScript:拦截表单提交并确定提交的表单

JavaScript: Intercepting form submit and identifying which form made the submission

本文关键字:提交 表单 表单提交 JavaScript      更新时间:2023-09-26

我正试图拦截来自我无法控制的网页的表单提交。

我目前的实现是。。。

// During onLoad, loop through all forms and for each form object
var prevonsubmit = formobj.onsubmit;
if (prevonsubmit) {
    formobj.onsubmit = function f() {
        if(prevonsubmit()) {
            interceptform();
            return true;
        }
        return false;
    };
} else {
    formobj.onsubmit = function ff() {
        interceptform();
        return true;
    };
}

问题是,在interceptform()中,我无法确定是哪个表单真正提交了此提交。有没有一种方法可以让我真正获得正在尝试提交的表单对象?请记住,我看到的一些表单没有指定名称或id,并且有多个表单(在同一网页中)具有相同的操作。

编辑:目的是捕获属于表单的输入标记中的内容。我在表格中看到的一个虚构的例子:

<form action="https://duckduckgo.com/html/" method="GET">
    <input type="text" name="q"/>
</form>
<form action="https://duckduckgo.com/html/" method="GET">
    <input type="text" name="l"/>
</form>
<form action="https://duckduckgo.com/html/" method="GET">
    <input type="text" name="l"/>
    <input type="text" name="q"/>
</form>

第2版:

根据@ruakh的回答,我最终使用的解决方案是:

var prevonsubmit = formobj.onsubmit;
if (prevonsubmit) 
    formobj.onsubmit = createOnSubmitFunctionWithOld(prevonsubmit, formobj);
else
    formobj.onsubmit = createOnSubmitFunction(formobj);
// Definition of the functions:
function createOnSubmitFunctionWithOld(prevonsubmit,formObj) {
    return function () {
        if (prevonsubmit()) {
            interceptform(formObj);
            return true;
        }
        return false;
    };
}
function createOnSubmitFunction(formObj) {
    return function () {
        interceptform(formObj);
        return true;
    };
}

您可以简单地将formobj作为参数传递给interceptform():

        interceptform(formobj);

但请记住,无论是使用formobj还是使用prevonsubmit,都必须小心避免捕获不想要的变量

var functions = [];
for(var i = 0; i < 10; ++i)
    { functions[i] = function() { return i; }; }

创建了十个函数,这些函数都返回10,因为它们都捕获了相同的i变量,该变量在调用函数时已增加到10。在上面的例子中,你可以写这样的东西:

function new_constant_function(return_value)
    { return function() { return return_value; }; }
// ...
var functions = [];
for(var i = 0; i < 10; ++i)
    { functions[i] = new_constant_function(i); }

将CCD_ 8的每个值复制到其值从未改变的新的局部变量CCD_;或者,更简洁一点,这个:

var functions = [];
for(var i = 0; i < 10; ++i)
    { functions[i] = (function(_i){ return function(){ return _i; } })(i); }

在你的情况下,你几乎肯定需要做一些类似的事情。(但是,如果看不到更多代码的上下文,就很难说具体是什么。)

为什么不循环遍历document.forms并为每个表单附加一个隐藏字段,或者为表单本身分配一个id。

如果您正在从一个函数循环遍历表单,那么:

> var prevonsubmit = formobj.onsubmit;
> if (prevonsubmit) {
>      formobj.onsubmit = function f() {
>          if(prevonsubmit()) {

prevonsubmit对外部变量有一个闭包,它将引用prevonssubmit的最后一个值,因此它们都将引用相同的函数。这可能"有效",但如果您的任何表单有一个不同于任何其他表单的当前侦听器,则会失败

>              interceptform();

您可以简单地将这个从函数传递到截取表单

               interceptform(this);

interceptform将被传递到调用函数的元素的引用(可能是提交的表单)。

>              return true;
>          }
>          return false;

这将(可能)取消任何没有现有侦听器的表单的提交。这就是你想要的吗?

>      };
>  } else {
>      formobj.onsubmit = function ff() {

已知命名函数表达式在至少一个广泛使用的浏览器中存在缺陷。如果你不需要一个名字(这里似乎没有任何名字),就不要用它。保持函数匿名。

>          interceptform();
>          return true;
>      };
>  }