是否可以自定义reCAPTCHA表单参数( recaptcha_challenge_field 和 recaptcha_response_field )以便以不同方式调用它们?
基本上我希望将表单参数 recaptcha_challenge_field 称为 captchaId , 和 recaptcha_response_field 被称为 captchaUserResponse 。
我希望将它们重命名,以便我可以抽象验证码实现 ......当请求到达时
POST / mysite / userSignup
我不想打扰验证码实现(reCaptcha,或将来的其他东西) - 为正确的验证码实现提取正确的参数,我想统一这些参数名称。
现在我的请求看起来像这样:
POST /mysite/userSignup HTTP/1.1
Host: localhost:80
Connection: keep-alive
Content-Length: 416
Cache-Control: max-age=0
Origin: http://localhost:80
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.46 Safari/536.5
Content-Type: application/x-www-form-urlencoded
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Referer: http://localhost:8080/mysite/signup/form.html
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8,hr;q=0.6
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
email:testUser%40gmail.com
username:testUser
password:test
password2:test
forename:Test
surname:User
recaptcha_challenge_field:<google generated challange>
recaptcha_response_field:<user typed captcha answer>
submit:Submit
但我希望它看起来像这样:
POST /mysite/userSignup HTTP/1.1
Host: localhost:80
Connection: keep-alive
Content-Length: 416
Cache-Control: max-age=0
Origin: http://localhost:80
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.46 Safari/536.5
Content-Type: application/x-www-form-urlencoded
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Referer: http://localhost:8080/mysite/signup/form.html
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8,hr;q=0.6
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
email:testUser%40gmail.com
username:testUser
password:test
password2:test
forename:Test
surname:User
captchaId:<google generated challange>
captchaUserResponse:<user typed captcha answer>
submit:Submit
一种优雅的方法是指定这样的表单参数名称:
<script>
var RecaptchaOptions = {
recaptcha_challenge_field_formparam_name : 'captchaId',
recaptcha_response_field_formparam_name: 'captchaUserResponse'
};
</script>
如果无法做到这一点,您建议使用哪种解决方法?
答案 0 :(得分:3)
这不应该是可能的。可能的解决方案AFAIU是添加新的DOM元素,它们在表单提交之前复制原始值的元素,例如:
<!-- the HTML part -->
<input type="hidden" id="captchaId">
<input type="hidden" id="captchaUserResponse">
// the JavaScript (jQuery) part
$('form').submit(function(){
$('input#captchaId').
val($('input#recaptcha_response_field').val());
$('input#captchaUserResponse').
val($('input#recaptcha_challenge_field').val());
return true;
})
答案 1 :(得分:3)
由于OP尚未接受任何答案,我正在提供此答案。这正是OP在这篇文章的评论中所寻找的确切内容:one of the answers
创建一个PHP脚本并将其放在某处。我假设创建的页面的URI是DESIRED_URI
。将此代码放在其中:
<?php
header("Content-type: text/javascript");
/*
* These are the script parameters
* You can change them by including desired ones in script's URL (as GET params)
* challenge_field_original: original name of captcha challenge field
* response_field_original: original name of captcha response field
* to_challenge_field: the name of the challenge field you want
* to_response_field: the name of the response field you want
*/
$params = array(
/*
* Defining the defaults of the parameters
*/
"challenge_field_original" => "recaptcha_challenge_field",
"response_field_original" => "recaptcha_response_field",
"to_challenge_field" => "captchaId",
"to_response_field" => "captchaUserResponse",
);
/*
* Checking for passed GET params to re-fill the parameters with non-default ones (if any)
*/
if(isset($_GET['challenge']) && $_GET['challenge'] != "") {
$params["to_challenge_field"] = $_GET['challenge'];
}
if(isset($_GET['response']) && $_GET['response'] != "") {
$params["to_response_field"] = $_GET['response'];
}
if(isset($_GET['challenge_original']) && $_GET['challenge_original'] != "") {
$params["challenge_field_original"] = $_GET['challenge_original'];
}
if(isset($_GET['response_original']) && $_GET['response_original'] != "") {
$params["response_field_original"] = $_GET['response_original'];
}
?>
/*
* I'm going to find the index of this script tag in the whole document
* So I can find its previous sibling node (the captcha form node)
*/
var scripts = document.getElementsByTagName( 'script' );
var thisScriptTag = scripts[ scripts.length - 1 ];
//now we have the index, good, I'm going to find its previous sibling node
var targetFormTag = (function(element) {
if(typeof(element.previousElementSibling) == "undefined") {
var p = element;
do p = p.previousSibling;
while (p && p.nodeType != 1);
return p;
} else {
return element.previousElementSibling;
}
})(thisScriptTag);
//Changing names...
(function(targetForm) {
var a = targetForm.getElementsByTagName('input');
var attr = '';
var toAttr = '';
for (var i in a) {
try {
attr = a[i].getAttribute('name')
} catch(e) {
continue;
}
switch(attr) {
case '<?php echo $params["challenge_field_original"]; ?>':
{toAttr='<?php echo $params["to_challenge_field"]; ?>';break;}
case '<?php echo $params["response_field_original"]; ?>':
{toAttr='<?php echo $params["to_response_field"]; ?>';break;}
}
a[i].setAttribute('name',toAttr);
}
})(targetFormTag)
<强> 用法:的强>
就像在表单 之后包含脚本 一样简单(!这非常重要!)。像这样:
<form><!--form elements--></form>
<script type="text/javascript" src="DESIRED_URI"></script>
您可以在一段时间后更改字段的名称,为此,阅读代码的文档。
<强> 侧面说明: 强>
src
中提供原始输入的名称和该输入字段的所需名称。答案 2 :(得分:2)
不需要额外的字段。您所要做的就是使用id标识表单元素并在提交之前更改其相对名称。
假设您有以下表格:
<div id="captcha" class="item recaptcha">
...
<textarea id=custom1 name="recaptcha_challenge_field" rows="3" cols="40"></textarea>
<input id=custom2 name="recaptcha_response_field" value="manual_challenge" type="hidden" />
<input type="submit" name="submit" value="Submit">
</div>
您可以使用
更改名称document.captcha.custom1.name='captchaId'
document.captcha.custom2.name='captchaUserResponse'
这些更改可以直接或间接地包含在提交按钮中(使用onclick事件调用另一种方法)。
因此,对于直接更改,您的提交将是:
<input type="submit" name="submit" value="Submit" onclick="document.captcha.custom1.name='captchaId';document.captcha.custom2.name='captchaUserResponse';return true">
答案 3 :(得分:2)
你走了,我和你处于同样的境地,这就是我的成就:
简短版本:
在这里,将此属性添加到表单中,这就是您所需要的:
EDIT2 - 添加了纯Javascript代码:
纯Javascript方法
在IE8,FF12和Chrome上测试:
onsubmit="javascript:(function(p){var a=p.getElementsByTagName('input');var attr='';var toAttr='';for (var i in a){try {attr=a[i].getAttribute('name')} catch(e) {continue;}switch(attr){case 'recaptcha_challenge_field':{toAttr='captchaId';break;}case 'recaptcha_response_field':{toAttr='captchaUserResponse';break;}}a[i].setAttribute('name',toAttr);}p.submit();})(this)"
jQuery方法:
onsubmit="javascript:(function(p){var f=$(p);$('input[name=recaptcha_challenge_field]',f).attr('name','captchaId');$('input[name=recaptcha_response_field]',f).attr('name','captchaUserResponse');f.submit();})(this)"
E.G:
<form method="post" action="verify.php" onsubmit="javascript:(function(p){var f=$(p);$('input[name=recaptcha_challenge_field]',f).attr('name','captchaId');$('input[name=recaptcha_response_field]',f).attr('name','captchaUserResponse');f.submit();})(this)">
<?php
require_once('recaptchalib.php');
$publickey = "your_public_key"; // you got this from the signup page
echo recaptcha_get_html($publickey);
?>
<input type="submit" />
</form>
长版:
这就是我正在做的事情:
1 - 这是实际的javascript函数,它负责替换输入的名称,这里没什么特别的:
function(param){
var form = $(param);
$('input[name=recaptcha_challenge_field]',form).attr('name','captchaId');
$('input[name=recaptcha_response_field]',form).attr('name','captchaUserResponse');
form.submit();
}
2 - 我将创建上述函数,这是一个匿名函数,因此我可以通过内联HTML事件(onsubmit
事件)调用它:
(function(param){...function code...})(this)
(this)
?在我们的匿名函数结束?通过
这个,我可以将我们表单的句柄传递给函数。 3 - 由于您需要尽可能少的客户端修改(或您说干预?),我将从HTML内联事件处理程序中调用此匿名函数。在我们的例子中,最好的处理程序是onsubmit
。
老实说,我自己很喜欢这个解决方案,希望它也对你有用:D
<强> EDIT1:强>
顺便说一下,如果你想以这种方式做到这一点,我没有注意到你的意见:
<form><!--blah blah--></form>
<script type="text/js" src="somewhere"></script>
这些是缺点:
答案 4 :(得分:2)
你想要一种处理验证码的通用方法,所以如果你决定使用reCAPTCHA之外的其他东西,你可以用同样的方式处理它。我认为你的思想很棒,但你的思想太过深刻。
理想情况下,您需要一些黑盒验证码系统才能完成它,您不必担心盒子中有哪个验证码插件。你需要离开那个盒子的唯一一件事就是用户是否输入了正确的东西。
如果您试图决定黑盒子如何进行此检查,那么您正在捣乱盒子。此外,如果你最终切换到另一个验证码插件,你也必须使用那个插件。
由于这些原因,我建议你只抽象出一件事:is_human_user
方法(或任何你想要的方法)。您需要做的就是为您决定使用的每个captcha插件实现此方法。对于reCAPTCHA,听起来这个方法会返回recaptcha_challenge_field == recaptcha_response_field
。然后,无论检查只是调用is_human_user
,并且对实现的内容都是盲目的。
如果这不是您正在寻找的答案,我很抱歉,但重要的是退后一步并提醒自己为什么要打败那个兔子洞。
答案 5 :(得分:1)
我相信你不能抽象太多的验证码实现,因为每个验证码都使用它自己的验证函数,无论如何改变客户端的验证码字段的名称它不是最好的解决方案,因为如果客户端没有启用JavaScript后,它将无法正常工作。
考虑到这一点,我认为抽象字段名称的最佳方法是在服务器端使用变量,在收到表单的帖子后,您可以这样做:
$captchaId = $_POST["recaptcha_challenge_field"];
$captchaUserResponse = $_POST["recaptcha_response_field"];
然后将其传递给通用验证函数,如下所示:
recaptcha_generic_check ("PrivateKey", $_SERVER["REMOTE_ADDR"], $captchaId, $captchaUserResponse);
理想情况下,这种方式只需要更改帖子中收到的字段名称(当然还有功能),一切都会保持不变。