在提交表单和打开新标签之前重定向JavaScript

时间:2017-05-10 09:47:57

标签: javascript forms redirect

我有一种情况,当用户点击"提交"时,我需要在外部网站上打开新标签页。在表单上,​​同时我需要将原始标签重定向到另一个页面,以防止用户向外部网站发出多个重复请求。

注意: 在后端保护免受此行为的影响,我只想在可能的情况下使用JavaScript来改进UX,删除选项的呈现首先。

注2:这适用于Firefox,但不适用于Chrome或Safari。

说明我的问题的一些示例代码如下所示:

<script type="text/javascript">
    function testFunction(){
        alert("Executing testFunction()!");
        window.location.replace("http://www.google.com");
    }
    // uncomment this line to show that testFunction() does work when called directly
    //testFunction();
</script>
<html>
    <head>
        <title>JS Redirect Then Post Test</title>
    </head>
    <body>
            <form action="" method="POST" target="_blank">
                First name: <input type="text" name="firstname"><br>
                Last name: <input type="text" name="lastname"><br><br>
                <input type="submit" value="Submit" onclick="testFunction()">
            </form>
    </body>
</html>

当我点击提交时,我会观察到警告弹出,但重定向不会执行。

如果我取消注释直接调用testFunction()的行,它将按预期工作。

我怎样才能得到我正在寻找的行为?

1 个答案:

答案 0 :(得分:1)

这是我在经过一些修修补补后想到的。您可以将onclick中的click事件传递给处理函数。如果您让事件发生,它只会提交表单并阻止所有后续执行,这就是我使用preventDefault停止原始点击事件并以编程方式触发form.submit()的原因。 另请注意我如何将重定向包装在setTimeout内,以便在重定向之前为submit()提供实际发生的时间。

<html>
<head>
    <script type="text/javascript">
        function testFunction(e) {
            e.preventDefault();
            e.target.parentNode.submit();
            alert("Executing testFunction()!");
            setTimeout(function() {
                document.location.href = "http://www.google.com";
            }, 0);

        }
        // uncomment this line to show that testFunction() does work when called directly
        // testFunction();
    </script>
    <title>JS Redirect Then Post Test</title>
</head>
<body>
    <form action="" method="POST" target="_blank">
        First name: <input type="text" name="firstname"><br> Last name: <input type="text" name="lastname"><br><br>
        <input type="submit" value="Submit" onclick="testFunction(event)">
    </form>
</body>
</html>