我正在尝试通过Marketing Cloud-Cloud页面实现reCAPTCHA验证。
我使用本指南做到了这一点:https://ampscript.xyz/how-tos/how-to-implement-google-recaptcha-on-marketing-cloud-forms/
我想做的是创建一个post请求,而不是使用action form属性。
我的Clint侧脚本:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://www.google.com/recaptcha/api.js"></script>
</head>
<body>
<form id="form" >
<label>Email: </label>
<input type="email" name="EmailAddress">
<div
class="g-recaptcha"
data-sitekey="XXXXXXXXXXXXXXXXXXXXXX"
data-callback="grecaptchaCallback"
data-size="invisible"
></div>
<br>
<button>Send</button>
</form>
<script>
var form = document.getElementById('form');
form.addEventListener('submit', grecaptchaValidate);
function grecaptchaCallback() {
return new Promise(function (resolve, reject) {
if (grecaptcha.getResponse() !== '') {
var x=grecaptcha.getResponse();
console.log(x);
var xhttp = new XMLHttpRequest();
xhttp.open("POST", "https://pub.s7.exacttarget.com/jnmlkgsfquv", true);
xhttp.setRequestHeader("Content-type", 'text/html',['Accept-Encoding'], ['identity'] );
xhttp.send();
http.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var response=this.responseText;
console.log(response);
response=response.split("<script>");
console.log(response);
console.log(response[0].trim());
}
}
}
grecaptcha.reset();
})
}
function grecaptchaValidate(e) {
e.preventDefault();
grecaptcha.execute();
}
</script>
</body>
</html>
</script>
</body>
</html>
这是我的服务器端脚本:
<script runat="server">
Platform.Load("core", "1.1.1");
try {
var g_recaptcha_response = Request.GetFormField("g-recaptcha-response");
var secret = "XXXXXXXXXXXXXXXXXXXXXXXXXXX";
var payload = "secret=" + secret + "&response=" + g_recaptcha_response;
var contentType = "application/x-www-form-urlencoded";
var endpoint = "https://www.google.com/recaptcha/api/siteverify";
var req = HTTP.Post(endpoint, contentType, payload);
if (req.StatusCode == 200) {
var resp = Platform.Function.ParseJSON(String(req.Response));
if (!resp.success) throw "Wrong reCAPTCHA";
} else {
throw "reCAPTCHA API error";
}
/// DO SOMETHING
Write(Stringify(resp));
} catch (error) {
Write(Stringify({ status: "Error", message: error }));
}
</script>
当我发送请求时,我得到的错误是:
{"status":"Error","message":"Wrong reCAPTCHA"}
<script>(function(a,m,i,g,o,s){o=a.createElement(g);s=a.getElementsByTagName(i)[0];o.src=m.origin+m.pathname+"/_t?eventType=CLOUDPAGESVISIT";o.width=0;o.height=0;o.style.display="none";s.appendChild(o);})(document,window.location,"body","img");</script>
<script src="https://7231513.collect.igodigital.com/collect.js"></script>
<script>
if (_etmc && typeof _etmc.push === 'function') {
_etmc.push(['setOrgId', '7231513']);
_etmc.push(['trackPageView']);
}
</script>
我得出的另一个结论是——如果我手动插入从x对象(grecaptcha.getResponse(((从客户端收到的值响应正确:
{"success":true,"challenge_ts":"2020-07-29T09:30:03Z","hostname":"pub.s7.exacttarget.com"}
我很想知道如何根据我发起的帖子创建从客户端到服务器端页面的请求
我缺什么了吗?或者我工作不正常?
编辑:
服务器端页面上的有效负载出现问题,因为变量g_repatcha_response为null。
我的解决方法是用查询字符串变量捕获变量:
%%[
set @x = RequestParameter("x")
]%%
<script runat="server">
Platform.Load("core", "1.1.1");
var x = Variable.GetValue("@x");
try {
// var g_recaptcha_response = Request.GetFormField("g-recaptcha-response");
var secret = "XXXXXXXXXXXXXXXXXXXXXXXXX";
var payload = "secret=" + secret + "&response=" + x;
var contentType = "application/x-www-form-urlencoded";
var endpoint = "https://www.google.com/recaptcha/api/siteverify";
var req = HTTP.Post(endpoint, contentType, payload);
if (req.StatusCode == 200) {
var resp = Platform.Function.ParseJSON(String(req.Response));
if (!resp.success) throw "Wrong reCAPTCHA";
} else {
throw "reCAPTCHA API error";
}
/// DO SOMETHING
Write(Stringify(resp));
} catch (error) {
Write(Stringify({ status: "Error", message: error }));
}
</script>
因为没有办法在SSJS I上使用AMPscript捕获x并将其传递给有效负载来捕获URL数据,所以现在我得到了成功的响应。
但我不确定这种方式是否存在任何安全问题。
首先,您需要使用Content Builder选项创建云页面。这将删除响应中的script
标记。
其次,如果要以text/html
的内容类型发送数据,请尝试使用application/x-www-form-urlencoded
。
我相信,您的表单处理程序不会捕获g-recaptcha-response
,因为当您发送text/html
内容类型时,无法使用Request.GetFormField检索它。
请看一下这篇文章:https://ampscript.xyz/how-tos/perform-an-http-request/
否则,请使用Axios处理客户端请求:https://github.com/axios/axios