Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/237.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 是否可以在页面上检测表单提交并执行我的操作,然后让表单继续正常运行?_Javascript_Php_Jquery_Forms - Fatal编程技术网

Javascript 是否可以在页面上检测表单提交并执行我的操作,然后让表单继续正常运行?

Javascript 是否可以在页面上检测表单提交并执行我的操作,然后让表单继续正常运行?,javascript,php,jquery,forms,Javascript,Php,Jquery,Forms,我正在为WordPress构建一个登录页a/B测试插件 我的目标是建立一些规则,当满足这些规则时,将在当前登录页a/B测试变体上记录转换 到目前为止,我有几个想法 1) JavaScript事件处理程序 使用JavaScript,检测submit事件并触发AJAX post,以在事件处理程序中记录我的转换。在AJAX成功回调中,我将继续这篇文章。一种方法是将标志变量设置为false,然后在AJAX成功中将其设置为true。然后它将再次触发表单上的提交,但这次标志var将使它绕过AJAX转换保存,

我正在为WordPress构建一个登录页a/B测试插件

我的目标是建立一些规则,当满足这些规则时,将在当前登录页a/B测试变体上记录转换

到目前为止,我有几个想法

1) JavaScript事件处理程序 使用JavaScript,检测submit事件并触发AJAX post,以在事件处理程序中记录我的转换。在AJAX成功回调中,我将继续这篇文章。一种方法是将标志变量设置为false,然后在AJAX成功中将其设置为true。然后它将再次触发表单上的提交,但这次标志var将使它绕过AJAX转换保存,而只执行正常的表单post操作

2) 将表单操作URL更改为通过本地服务器路由帖子,然后转发到目标 使用JavaScript,在DOM中找到所有匹配的表单,并用我的服务器上的新URL替换那里的post-action URL。新的URL会将表单发布到我的服务器,这样我就可以用PHP检测帖子并记录转换,然后再将原始表单发布数据重新发布到原始URL

function redirect_post2($url, array $data)
{
    ?>
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <script type="text/javascript">
            function closethisasap() {
                document.forms["redirectpost"].submit();
            }
        </script>
    </head>
    <body onload="closethisasap();">
    <form name="redirectpost" method="post" action="<?php echo $url; ?>">
        <?php
        if ( !is_null($data) ) {
            foreach ($data as $k => $v) {
                echo '<input type="hidden" name="' . $k . '" value="' . $v . '"> ';
            }
                echo '<input type="hidden" name="test" value="testval"> ';
        }
        ?>
    </form>
    </body>
    </html>
    <?php
    exit;
}
/**
 * Redirect with POST data.
 *
 * @param string $url URL.
 * @param array $post_data POST data. Example: array('foo' => 'var', 'id' => 123)
 * @param array $headers Optional. Extra headers to send.
 */
function redirect_post($url, array $data, array $headers = null) {
    $params = array(
        'http' => array(
            'method' => 'POST',
            'content' => http_build_query($data)
        )
    );
    if (!is_null($headers)) {
        $params['http']['header'] = '';
        foreach ($headers as $k => $v) {
            $params['http']['header'] .= "$k: $v\n";
        }
    }
    $ctx = stream_context_create($params);
    $fp = @fopen($url, 'rb', false, $ctx);
    if ($fp) {
        echo '<pre>';
        echo @stream_get_contents($fp);
        echo '</pre>';
        die();
    } else {
        // Error
        throw new Exception("Error loading '$url', $php_errormsg");
    }
}
表单操作URL如下:
https://www.remote-server.com

将成为
https://www.local-server.com/?record-转换=是&id=123&原始url=https://www.remote-server.com

然后在PHP中,我可以从
$\u post['original-URL']

为了将文章转发到原始URL,我遇到了2个PHP函数

版本1
将表单POST数据作为隐藏表单字段打印到HTML页面,然后使用JavaScript将其触发以立即提交表单,并将数据发布到原始URL

function redirect_post2($url, array $data)
{
    ?>
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <script type="text/javascript">
            function closethisasap() {
                document.forms["redirectpost"].submit();
            }
        </script>
    </head>
    <body onload="closethisasap();">
    <form name="redirectpost" method="post" action="<?php echo $url; ?>">
        <?php
        if ( !is_null($data) ) {
            foreach ($data as $k => $v) {
                echo '<input type="hidden" name="' . $k . '" value="' . $v . '"> ';
            }
                echo '<input type="hidden" name="test" value="testval"> ';
        }
        ?>
    </form>
    </body>
    </html>
    <?php
    exit;
}
/**
 * Redirect with POST data.
 *
 * @param string $url URL.
 * @param array $post_data POST data. Example: array('foo' => 'var', 'id' => 123)
 * @param array $headers Optional. Extra headers to send.
 */
function redirect_post($url, array $data, array $headers = null) {
    $params = array(
        'http' => array(
            'method' => 'POST',
            'content' => http_build_query($data)
        )
    );
    if (!is_null($headers)) {
        $params['http']['header'] = '';
        foreach ($headers as $k => $v) {
            $params['http']['header'] .= "$k: $v\n";
        }
    }
    $ctx = stream_context_create($params);
    $fp = @fopen($url, 'rb', false, $ctx);
    if ($fp) {
        echo '<pre>';
        echo @stream_get_contents($fp);
        echo '</pre>';
        die();
    } else {
        // Error
        throw new Exception("Error loading '$url', $php_errormsg");
    }
}
'; 模具(); }否则{ //错误 抛出新异常(“加载'$url',$php_errormsg'时出错”); } }
问题/问题/担忧
  • 如果我使用JavaScript事件处理程序检测表单post并记录我的转换。我不确定当同一表单post/提交的其他事件处理程序存在时会发生什么。我不确定这是否会让我的车不跑?如果我的跑了,其他人也跑了。其他处理程序可能会提交帖子,而我的帖子可能会导致表单提交超过1次

  • 如果表单使用AJAX提交帖子。然后我的代码将尝试执行页面重定向帖子并破坏功能


我的目标可能实现吗? 这让我提出了一个问题。我是否有可能将现有表单插入到一个页面,并在表单提交时记录我的转换,并让表单仍能正常运行,而不让我试图干扰它?

您需要设置Submit attr。在表格上

html

在chrom dev上进行100%测试

如果要运行ajax,然后如果回答为true,则继续表单,则需要将javascript更改为:

function handleSubmit(form) {
    // Make your ajax call
    $.ajax({
        ...,
        onsuccess: {
            form.submit();
        }
    })
}
而不是xhttp.open()中的x;以字符串形式键入文件

如果缓存不是一个选项,那么更改GET to POST,它的速度较慢但安全

0%已测试


要详细说明我的评论

如果您事先不知道表单是如何工作的,那么您可以接近——并涵盖您将在野外看到的绝大多数情况——但在某些情况下,您会破坏表单

假设您执行以下所有操作:

  • 检测目标形状
  • 迭代所有元素,记录所有事件处理程序
  • 清除所述事件处理程序(不破坏验证…)
  • 将您自己的事件处理程序添加到表单
    submit
    和所有按钮(希望表单不是通过键入特定值或其他奇怪的内容提交的,并且所有按钮都确实提交了表单)
  • 等待点击
  • 记录按钮/事件
  • 进行AJAX调用
  • 成功时(让我们忽略失败时发生的事情)
    • 还原所有原始事件处理程序
    • 尝试“重播”针对调用方法的元素录制的事件
    • 祝你好运
这将涵盖很多情况(当然是所有“正常”html表单使用),但是,它会在以下任何情况下中断:

  • 表格的提交取决于时间
  • 表单上的按钮完全做了其他事情(比如发出Ajax请求以验证用户名)
  • 事件详细信息的细节用于以某种方式处理表单(例如,在按钮上发生单击的位置)
  • 不处理根本没有“单击”提交的情况(在字段中键入特定值时,等等)
  • 不处理从表单外部调用提交的情况
  • 它还将破坏任何验证事件等
在剥离事件时,您可以不那么咄咄逼人,但这样您就更可能完全错过提交

一个稍微好一点的不同方法。。。 如果您自己的方法足够健壮,能够经受多次调用而不会产生任何副作用,那么您可以通过执行以下操作:

用您自己的包装器替换所有表单
onsubmit
事件处理程序,这些包装器可以执行以下操作

这应该可以处理“股票”案件。然后,为了处理原始表单使用jQuery Ajax的情况,设置一个函数来执行类似的操作(但是在本例中,您将调用原始回调,而不是提交表单)

现在您正在处理股票表单和jQueryAjax。当然,如果他们使用的是react/angular/不同的框架,那么您需要为这些框架添加一个处理程序

我想您可以全力以赴,尝试替换低级
XMLHttpRequest
function handleSubmit(form) {
    // Make your ajax call
    $.ajax({
        ...,
        onsuccess: {
            form.submit();
        }
    })
}