我正在为WordPress构建一个登陆页面A / B测试插件。
我的目标是设置一些符合规则的规则,这些规则会记录当前着陆页A / B测试变体的转换。
到目前为止,我有过几个想法......
使用JavaScript,检测提交事件并触发AJAX帖子以在事件处理程序中记录我的转换。在AJAX成功回调中,我将继续发布帖子。一种方法是将标志变量设置为false,然后在AJAX成功中将其设置为true。然后它会再次触发表单上的提交,但这次标志var将使其绕过AJAX转换保存,而只是执行正常的表单后期操作。
使用JavaScript,在DOM中查找所有匹配的表单,并使用我服务器上的新URL替换post post action URL。新的URL会将表单发布到我的服务器,以便我可以使用PHP检测帖子并记录转换,然后我将原始表单发布数据重新发布到原始URL。
表单操作网址如下:https://www.remote-server.com
会成为
https://www.local-server.com/?record-conversion=yes&id=123&original-url=https://www.remote-server.com
然后在PHP中,我可以从$_POST['original-url']
要将POST转发到原始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;
}
第2版
此版本使用PHP的stream_context_create()
,stream_get_contents()
和fopen()
将POST数据转发/发布到原始网址。
/**
* 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");
}
}
如果我使用JavaScript事件处理程序检测表单帖子并记录我的转换。我不确定当存在同一表单发布/提交的其他事件处理程序时会发生什么。我不确定它是否会让我不能跑?如果我的确运行,而其他人也这样做。其他处理人员可能会提交帖子,然后我的提交可能会导致表格被提交超过1次!?
如果表格使用AJAX提交其帖子。然后我的代码将尝试执行页面重定向帖子并破坏功能!
所以这让我问这个问题。是否可以插入包含现有表单的页面,并且能够在提交表单时记录我的转换并使表单仍然完全像我试图干扰它一样执行?
答案 0 :(得分:1)
扩展我的评论......
如果你事先没有关于表格如何运作的知识,你可以近距离接触 - 并覆盖你将在野外看到的绝大多数情况 - 但是在某些情况下你会打破形式。
假设您执行以下所有操作:
submit
和所有按钮(我们希望通过键入特定值或其他奇怪的内容来提交表单,并且所有按钮实际上都提交了表单)这将涵盖很多情况(当然所有“正常”的html表单使用),但是,它会在以下任何情况下中断:
在删除事件时你可能不那么激进,但是你更有可能完全错过提交。
如果您自己的方法足够强大,可以在没有副作用的情况下多次调用,那么您可以放弃执行以下操作:
使用您自己的包装器替换所有形式onsubmit
事件处理程序,这些包装器执行类似
function handleSubmit(form) {
// Make your ajax call
$.ajax({
...,
onsuccess: {
form.submit();
}
})
}
那应该处理“股票”案件。然后,为了处理原始表单使用jQuery Ajax的情况,设置一个jQuery.ajaxPrefilter()来执行类似的操作(但在这种情况下,不是提交表单,而是调用原始回调)。
现在你正在处理股票表格和jQuery AJAX。当然,如果他们使用的是react / angular /一个不同的框架,你需要为这些框架添加一个处理程序。
我想你可以全力以赴,尝试替换低级XMLHttpRequest
(以及不同浏览器中的相关等价物),但那将是真的脆弱。
在一天结束时,你将报名参加军备竞赛,我不认为这是你能赢的。
答案 1 :(得分:0)
您需要设置 onsubmit attr。在表格上。
HTML
<form onsubmit="Get();" method="post" action="example.php">
<input type="text" name="name" placeholder="name">
<input type="submit" value="Go">
</form>
的javascript
var Get = function(){
//action to do
return true
};
100%testing.on chrom dev。
如果你想运行ajax然后如果回答为true,则继续表格,然后你需要将javascript更改为:
var Get = function(){
var xhttp;
if (window.XMLHttpRequest) {
xhttp = new XMLHttpRequest();
} else {
xhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xhttp.onreadystatechange = function() {
if (xhttp.readyState == 4 && xhttp.status == 200) {
if (xhttp.responseText == "true"){
return true;
}else{
alert("There is some error in verfication.");
return false;
break;
}
}else{
alert("Oops error " + xhttp.State + " happends.");
return false;
break;
}
};
xhttp.open("GET" , x, true);
/* add
xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
if using post*/
xhttp.send();
};
而不是xhttp.open()中的x;将文件键入为字符串。
如果缓存不是一个选项,那么将GET更改为POST,它更慢但安全。
0%测试