[英]How to validate captcha within an online form
My job is to create a form for a competition and collect the data. 我的工作是为比赛创建表单并收集数据。 This data will be collected by a company that we use to send e-mails (think Mail chimp).
此数据将由我们用来发送电子邮件的公司收集(请考虑“邮件黑猩猩”)。 This company (email vision through their online software "campaign commander") has generated the form below.
该公司(通过其在线软件“广告活动指挥官”发送电子邮件愿景)已生成以下表格。 as you can see it does not validate captcha.
如您所见,它不验证验证码。 What code do I need to make it validate captcha without leaving the form?
我需要什么代码才能使它在不离开表单的情况下验证验证码? The site was developed in PHP.
该网站是用PHP开发的。 Thank you for your help.
谢谢您的帮助。 and God bless us.
上帝保佑我们。 Julian P.
朱利安·P。
<html>
<head>
<title>Webform</title>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<script language="javascript">
function isInteger(input,fieldName){
var i;
for(i=0;i<input.value.length;i++){
var c=input.value.charAt(i);
if(((c<'0')||(c>'9'))){
alert('The number in '+fieldName+' is not valid.');
input.focus();
return false;
}}
return true;
}
var dtCh='/';
var minYear=1900;
var maxYear=2100;
function isValidInteger(s){
var i;
for(i=0;i<s.length;i++){
var c=s.charAt(i);
if(((c<'0')||(c>'9'))) return false;
}
return true;
}
function stripCharsInBag(s,bag){
var i;
var returnString='';
for(i=0;i<s.length;i++){
var c=s.charAt(i);
if(bag.indexOf(c)==-1) returnString+=c;
}
return returnString;
}
function daysInFebruary(year){
return(((year%4==0)&&((!(year % 100 == 0))||(year%400==0)))?29:28);
}
function DaysArray(n){
for(var i=1;i<=n;i++){
this[i]=31;
if(i==4||i==6||i==9||i==11){this[i]=30;}
if(i==2){this[i]=29;}
}
return this;
}
function isDateOK(dtStr){
if(dtStr=='') return true;
var daysInMonth=DaysArray(12);
var pos1=dtStr.indexOf(dtCh);
var pos2=dtStr.indexOf(dtCh,pos1+1);
var strDay=dtStr.substring(0,pos1);
var strMonth=dtStr.substring(pos1+1,pos2);
var strYear=dtStr.substring(pos2+1);
strYr=strYear;
if(strDay.charAt(0)=='0'&&strDay.length>1) strDay=strDay.substring(1);
if(strMonth.charAt(0)=='0'&&strMonth.length>1) strMonth=strMonth.substring(1);
for(var i=1;i<=3;i++){
if(strYr.charAt(0)=='0'&&strYr.length>1) strYr=strYr.substring(1);
}
month=parseInt(strMonth);
day=parseInt(strDay);
year=parseInt(strYr);
if(pos1==-1||pos2==-1){
alert('The date format should be : dd/mm/yyyy.');
return false;
}
if(strMonth.length<1||month<1||month>12){
alert('Please enter a valid month.');
return false;
}
if(strDay.length<1||day<1||day>31||(month==2&&day>daysInFebruary(year))||day>daysInMonth[month]){
alert('Please enter a valid day.');
return false;
}
if(strYear.length!=4||year==0||year<minYear||year>maxYear){
alert('Please enter a valid 4 digit year between '+minYear+' and '+maxYear+'.');
return false;
}
if(dtStr.indexOf(dtCh,pos2+1)!=-1||isValidInteger(stripCharsInBag(dtStr,dtCh))==false){
alert('Please enter a valid date.');
return false;
}
return true;
}
function modifyDateFormat(dt){
var valuesTable=dt.value.split(dtCh);
dt.value=valuesTable[1]+dtCh+valuesTable[0]+dtCh+valuesTable[2];
}
function isEmail(emailAddress){
emailAddressValue=emailAddress.value.toLowerCase();
var countryTLDs=/^(ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cat|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cu|cv|cx|cy|cz|de|dj|dk|dm|do|dz|ec|ee|eg|eh|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|st|sv|sy|sz|tc|td|tf|tg|th|tj|tk|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|um|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|yu|za|zm|zw)$/;
var gTLDs=/^(aero|asia|biz|cat|com|coop|edu|geo|gov|info|int|jobs|mil|mobi|museum|name|net|org|post|pro|tel|travel)$/;
var basicAddress=/^(.+)@(.+)$/;
var specialChars='\\(\\)><@,;:\\\\\\\"\\.\\[\\]';
var validChars='\[^\\s'+specialChars+'\]';
var validCharset='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzöå0123456789\'-_.+';
var quotedUser='(\"[^\"]*\")';
var atom=validChars+'+';
var word='('+atom+'|'+quotedUser+')';
var validUser=new RegExp('^'+word+'(\.'+word+')*$');
var symDomain=new RegExp('^'+atom+'(\.'+atom+')*$');
var matchArray=emailAddressValue.match(basicAddress);
if(emailAddress.value==''||emailAddress==null){
return true;
}
if(matchArray==null){
alert('The Email address doesn\'t seem to be correct,\nplease check syntax.');
emailAddress.focus();
return false;
}else{
var user=matchArray[1];
var domain=matchArray[2];
for(i=0;i<user.length;i++){
if(validCharset.indexOf(user.charAt(i))==-1){
alert('The Email address contains invalid characters,\nplease check the username.');
emailAddress.focus();
return false;
}
}
for(i=0;i<domain.length;i++){
if(validCharset.indexOf(domain.charAt(i))==-1){
alert('The Email address contains invalid characters,\nplease check the domain.');
emailAddress.focus();
return false;
}
}
if(user.match(validUser)==null){
alert('The Email address doesn\'t seem to be correct,\nplease check the username.');
emailAddress.focus();
return false;
}
var atomPat=new RegExp('^'+atom+'$');
var domArr=domain.split('.');
var len=domArr.length;
for(i=0;i<len;i++){
if(domArr[i].search(atomPat)==-1){
alert('The Email address doesn\'t seem to be correct,\nplease check the domain name.');
emailAddress.focus();
return false;
}
}
if((domArr[domArr.length-1].length==2)&&(domArr[domArr.length-1].search(countryTLDs)==-1)){
alert('The Email address doesn\'t seem to be correct,\nplease check domain suffix.');
emailAddress.focus();
return false;
}
if((domArr[domArr.length-1].length>2)&&(domArr[domArr.length-1].search(gTLDs)==-1)){
alert('The Email address doesn\'t seem to be correct,\nplease check domain suffix.');
emailAddress.focus();
return false;
}
if((domArr[domArr.length-1].length<2)||(domArr[domArr.length-1].length>6)){
alert('The Email address doesn\'t seem to be correct,\nplease check domain suffix.');
emailAddress.focus();
return false;
}
if(len<2){
alert('The Email address doesn\'t seem to be correct,\nplease check missing hostname.');
emailAddress.focus();
return false;
}
}
return true;
}
function mandatoryCheckBox(checkBox,fieldName){
var nbcheck=0;
if(checkBox.length==undefined){
if(checkBox.checked){ nbcheck++; }
}else{
for (counter=0;counter<checkBox.length;counter++){
if(checkBox[counter].checked){ nbcheck++; }
}
}
if(nbcheck==0){
alert('Please select your '+fieldName+'.');
return false;
}
return true;
}
function mandatoryDropDown(dropDown,fieldName){
if(dropDown.options[dropDown.options.selectedIndex].value == ""){
alert('Please select your '+fieldName+'.');
dropDown.focus();
return false;
}
return true;
}
String.prototype.trim = function() { return this.replace(/^\s*(\b.*\b|)\s*$/, "$1"); }
function mandatoryText(input,fieldName){
if(input.value.trim()==''||input==null){
alert('Please enter your '+fieldName+'.');
input.focus();
return false;
} else {
return true;
}
}
function validForm(){
if(!mandatoryText(document.getElementById('FIRSTNAME_FIELD'), 'First name')) return;
if(!mandatoryText(document.getElementById('LASTNAME_FIELD'), 'Surname')) return;
if(!mandatoryText(document.getElementById('DATEOFBIRTH_FIELD'), 'Date of birth')) return;
if(!isDateOK(document.getElementById('DATEOFBIRTH_FIELD').value)) return;
if(!mandatoryText(document.getElementById('EMAIL_FIELD'), 'Email')) return;
if(!isEmail(document.getElementById('EMAIL_FIELD'))) return;
if(!mandatoryText(document.getElementById('EMVCELLPHONE_FIELD'), 'Mobile')) return;
if(!isInteger(document.getElementById('EMVCELLPHONE_FIELD'), 'Mobile')) return;
if(!mandatoryDropDown(document.getElementById('STORE_NAME_FIELD'), 'Nearest shop')) return;
if(!mandatoryCheckBox(document.getElementById('emvForm').OPTIN_FIELD, 'Opt in to marketing emails')) return;
if(document.getElementById('DATEOFBIRTH_FIELD').value!='') modifyDateFormat(document.getElementById('DATEOFBIRTH_FIELD'));
document.getElementById('emvForm').submit();
if(document.getElementById('DATEOFBIRTH_FIELD').value!='') modifyDateFormat(document.getElementById('DATEOFBIRTH_FIELD'));
}
</script>
</head>
<body>
<form name="emvForm" id="emvForm" action="http://tre.emv3.com/D2UTF8" method="POST" target="_top">
<input type="hidden" name="emv_tag" value="876020001C384269" />
<input type="hidden" name="emv_ref" value="EdX7CqkdLe_d8SA9MOPQNCffL0p6Hq3D-jmueKEyWsbQKbo" />
<table>
<tr>
<td>
First name
</td>
<td>
<input type="text" id="FIRSTNAME_FIELD" name="FIRSTNAME_FIELD" value="" size="30" maxlength="64">
</td>
</tr>
<tr>
<td>
Surname
</td>
<td>
<input type="text" id="LASTNAME_FIELD" name="LASTNAME_FIELD" value="" size="30" maxlength="64">
</td>
</tr>
<tr>
<td>
Date of birth
</td>
<td>
<input type="text" id="DATEOFBIRTH_FIELD" name="DATEOFBIRTH_FIELD" value="" size="30" maxlength="64">
</td>
</tr>
<tr>
<td>
Email
</td>
<td>
<input type="text" id="EMAIL_FIELD" name="EMAIL_FIELD" value="" size="30" maxlength="64">
</td>
</tr>
<tr>
<td>
Mobile
</td>
<td>
<input type="text" id="EMVCELLPHONE_FIELD" name="EMVCELLPHONE_FIELD" value="" size="30" maxlength="64">
</td>
</tr>
<tr>
<td>
Nearest shop
</td>
<td>
<select id="STORE_NAME_FIELD" name="STORE_NAME_FIELD">
<option selected value=""></option>
<option value="Aberdeen ">Aberdeen </option>
<option value="Acton ">Acton </option>
<option value="Aldgate ">Aldgate </option>
<option value="Ashford ">Ashford </option>
<option value="Aylesbury ">Aylesbury </option>
<option value="Baker Street ">Baker Street </option>
<option value="Balham ">Balham </option>
<option value="Ballymena ">Ballymena </option>
<option value="Barnet ">Barnet </option>
<option value="Beckenham ">Beckenham </option>
<option value="Belfast ">Belfast </option>
<option value="Bethnal Green ">Bethnal Green </option>
<option value="Bexleyheath ">Bexleyheath </option>
<option value="Biggleswade ">Biggleswade </option>
<option value="Birmingham ">Birmingham </option>
<option value="Birmingham New Street ">Birmingham New Street </option>
<option value="Bishopsgate ">Bishopsgate </option>
<option value="Bond Street ">Bond Street </option>
<option value="Bromley ">Bromley </option>
<option value="Camberwell ">Camberwell </option>
<option value="Cambridge ">Cambridge </option>
<option value="Camden Town ">Camden Town </option>
<option value="Chelmsford ">Chelmsford </option>
<option value="Chelsea ">Chelsea </option>
<option value="Cheltenham ">Cheltenham </option>
<option value="Chester ">Chester </option>
<option value="Chiswick ">Chiswick </option>
<option value="Clacton-on-Sea ">Clacton-on-Sea </option>
<option value="Clapham High Street ">Clapham High Street </option>
<option value="Clapham Junction ">Clapham Junction </option>
<option value="Colchester ">Colchester </option>
<option value="Coleraine ">Coleraine </option>
<option value="Covent Garden ">Covent Garden </option>
<option value="Coventry ">Coventry </option>
<option value="Cricklewood ">Cricklewood </option>
<option value="Crouch End ">Crouch End </option>
<option value="Croydon ">Croydon </option>
<option value="Dalston ">Dalston </option>
<option value="Ealing ">Ealing </option>
<option value="Earls Court ">Earls Court </option>
<option value="Edgware ">Edgware </option>
<option value="Exeter ">Exeter </option>
<option value="Farringdon ">Farringdon </option>
<option value="Fleet Street ">Fleet Street </option>
<option value="Fulham ">Fulham </option>
<option value="Glasgow ">Glasgow </option>
<option value="Godalming ">Godalming </option>
<option value="Golders Green ">Golders Green </option>
<option value="Guildford ">Guildford </option>
<option value="Hackney ">Hackney </option>
<option value="Hammersmith ">Hammersmith </option>
<option value="Hampstead ">Hampstead </option>
<option value="Highbury ">Highbury </option>
<option value="Holborn ">Holborn </option>
<option value="Ipswich ">Ipswich </option>
<option value="Angel ">Angel </option>
<option value="Kensington ">Kensington </option>
<option value="Kentish Town ">Kentish Town </option>
<option value="Kilburn ">Kilburn </option>
<option value="Kings Lynn ">Kings Lynn </option>
<option value="Kingston ">Kingston </option>
<option value="Knightsbridge ">Knightsbridge </option>
<option value="Leadenhall Market ">Leadenhall Market </option>
<option value="Lewisham ">Lewisham </option>
<option value="Lisburn ">Lisburn </option>
<option value="Lincoln ">Lincoln </option>
<option value="Londonderry ">Londonderry </option>
<option value="Luton ">Luton </option>
<option value="Maidenhead ">Maidenhead </option>
<option value="Maidstone ">Maidstone </option>
<option value="Mansion House ">Mansion House </option>
<option value="Marble Arch ">Marble Arch </option>
<option value="Marlow ">Marlow </option>
<option value="Marylebone ">Marylebone </option>
<option value="Mayfair ">Mayfair </option>
<option value="Milton Keynes ">Milton Keynes </option>
<option value="Muswell Hill ">Muswell Hill </option>
<option value="Newbury ">Newbury </option>
<option value="Northampton ">Northampton </option>
<option value="Norwich ">Norwich </option>
<option value="Notting Hill Gate ">Notting Hill Gate </option>
<option value="Oxford ">Oxford </option>
<option value="Peckham ">Peckham </option>
<option value="Peterborough ">Peterborough </option>
<option value="Pimlico ">Pimlico </option>
<option value="Portobello ">Portobello </option>
<option value="Putney ">Putney </option>
<option value="Queensway ">Queensway </option>
<option value="Reading ">Reading </option>
<option value="Richmond ">Richmond </option>
<option value="Romford ">Romford </option>
<option value="Shepherds Bush ">Shepherds Bush </option>
<option value="Slough ">Slough </option>
<option value="Soho ">Soho </option>
<option value="South Kensington ">South Kensington </option>
<option value="Southend ">Southend </option>
<option value="St Johns Wood ">St Johns Wood </option>
<option value="Staines ">Staines </option>
<option value="Streatham ">Streatham </option>
<option value="Surbiton ">Surbiton </option>
<option value="Sutton ">Sutton </option>
<option value="Swiss Cottage ">Swiss Cottage </option>
<option value="Sydenham ">Sydenham </option>
<option value="Tooting ">Tooting </option>
<option value="Tottenham Court Road ">Tottenham Court Road </option>
<option value="Tunbridge Wells ">Tunbridge Wells </option>
<option value="Twickenham ">Twickenham </option>
<option value="Uxbridge ">Uxbridge </option>
<option value="Victoria ">Victoria </option>
<option value="Walthamstow ">Walthamstow </option>
<option value="Walworth Road ">Walworth Road </option>
<option value="Wandsworth ">Wandsworth </option>
<option value="Watford ">Watford </option>
<option value="Welwyn Garden City ">Welwyn Garden City </option>
<option value="Westminster ">Westminster </option>
<option value="Wimbledon ">Wimbledon </option>
<option value="Windsor ">Windsor </option>
<option value="Wokingham ">Wokingham </option>
<option value="Wood Green ">Wood Green </option>
<option value="Woolwich ">Woolwich </option>
</select>
</td>
</tr>
<tr>
<td>
</td>
<td>
<input type="hidden" id="STORE_EMAIL_FIELD" name="STORE_EMAIL_FIELD" value="">
</td>
</tr>
<tr>
<td>
</td>
<td>
<input type="hidden" id="WEB_HOME_FIELD" name="WEB_HOME_FIELD" value="">
</td>
</tr>
<tr>
<td>
</td>
<td>
<input type="hidden" id="SOURCE_FIELD" name="SOURCE_FIELD" value="St Petes">
</td>
</tr>
<tr>
<td>
Opt in to marketing emails
</td>
<td>
<input type="checkbox" id="OPTIN_FIELD" name="OPTIN_FIELD" value="true">
</td>
</tr>
<tr>
<td style="border:1px solid red">
<img id="captcha" src="/maininc/securimage/securimage_show.php" alt="CAPTCHA Image" />
</td>
<td>
<input type="text" name="captcha_code" size="10" maxlength="6" />
<a href="#" onclick="document.getElementById('captcha').src = '/maininc/securimage/securimage_show.php?' + Math.random(); return false">[ Different Image ]</a>
</td>
</tr>
<tr>
<td colspan="2" align="center">
<input type="button" value="Submit Form" onClick="javascript:validForm();">
</td>
</tr>
</table>
</form>
</body>
</html>
Validating a captcha is not done client-side for several, good reasons: 出于几个良好的原因,验证码没有在客户端执行:
If the code you pasted is actually what the company "sells", look for another supplier (it's bad code, honestly). 如果您粘贴的代码实际上是公司要“出售”的代码,请寻找其他供应商(说实话,这是不好的代码)。
The only thing you could do to validate the captcha without submitting the form is send an AJAX request, but be careful! 您无需提交表单即可验证验证码的唯一方法是发送AJAX请求,但要小心! This means that bots can just try random strings at will, each time sending a request and getting immediate feedback without having to send any other data than the captcha.
这意味着漫游器可以随意尝试随机字符串,每次发送请求并立即获得反馈,而不必发送验证码以外的任何其他数据。
Yes, captcha's are annoying, and bothersome and yes they ruin the user experience and yes they can enrage us all, but they are a necessary evil. 是的,验证码很烦人,很麻烦,是的,它们破坏了用户体验,是的,它们激怒了我们所有人,但这是必不可少的邪恶。 Just leave the captcha as it is, send it with the form and hope your users can figure them out.
只需保留验证码,将其与表格一起发送,并希望您的用户能弄清楚它们。
What do you mean by "validate CAPTCHA without leaving the form"? “不用离开表格即可验证CAPTCHA”是什么意思? You have to submit the form for the data to be sent to the server, anyway, so just validate it then.
无论如何,您都必须提交表单以将数据发送到服务器,因此只需对其进行验证。 You could add some kid of pre-validation to ensure the right answer is supplied, however any determined spammer will be able to remove your client-side validation.
您可以添加一些预验证的孩子,以确保提供正确的答案,但是,任何确定的垃圾邮件发送者都可以删除您的客户端验证。 You must do server-side validation to get any of the benefit that CAPTCHA provides.
您必须执行服务器端验证才能获得CAPTCHA提供的任何好处。
Do you have CAPTCHA image production working? 您有CAPTCHA影像制作工作吗? The big deal behind CAPTCHA is that one has to generate images of words or numbers mostly readable to humans but difficult for computer OCR, and then be able to validate that user-supplied input matches those images.
CAPTCHA背后的一个大问题是,必须生成大多数人都可读但对计算机OCR来说很难的单词或数字图像,然后才能验证用户提供的输入是否与这些图像匹配。 It's not something you're going to be able to do yourself if you're new to the field.
如果您是该领域的新手,那将不是您自己可以做的事情。
If you don't already have CAPTCHA images being produced, search online for CAPTCHA service providers. 如果尚未生成验证码图像,请在线搜索验证码服务提供商。 There are even some free ones like captchas.net (though I cannot vouch for their quality or reliability).
甚至还有一些免费的软件,例如captchas.net (尽管我不能保证其质量或可靠性)。
Also, I would like to add that there are measures you can take to reduce or eliminate spam that don't involve CAPTCHA: 另外,我想补充一点,您可以采取一些措施来减少或消除不包含验证码的垃圾邮件:
PS The email address validation in your question is not good. 附言:您问题中的电子邮件地址验证不正确。 It will prevent many completely valid characters from being used.
这将防止使用许多完全有效的字符。 For example, the name part of the address should allow much more than letters and numbers.
例如,地址的名称部分所允许的范围不能超过字母和数字。 In particular,
+
is a valid character and one many people use. 特别是,
+
是有效字符, 很多人使用。 Do not do that to your users. 不要对您的用户这样做。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.