联系表单与反垃圾邮件领域,PHP或JS问题

时间:2015-08-09 21:01:12

标签: javascript php jquery twitter-bootstrap

我有一个引导程序联系表单,我添加了一个简单的数学公式来防止垃圾邮件。表单使用contact_me.js处理表单并调用contact_me.php文件来验证并发送电子邮件。它还使用jqBootstrapValidation.js来验证表单。我使用了一个基本的bootstrap模板并为我的网站修改了模板,因此我没有创建实际的表单或php(或js)。

表单发送电子邮件就好了,但是"人类"我添加的数学方程式字段无法正常运行,因为无论数学答案是否正确,它都会发送电子邮件。我对PHP或JS知之甚少,但我非常了解HTML和CSS - 所以我知道问题出在PHP或JS上。任何人都可以帮助解决我需要更新的问题吗?

HTML表单代码:

<%= link_to "Adults and Children Only", category_path(@categories_to_show) %>

Contact_Me.php代码:

<div class="form-group col-xs-12 floating-label-form-group controls">
        <label>Email Address</label>
        <input type="email" class="form-control" placeholder="Email Address" id="email" required data-validation-required-message="Please enter your email address.">
        <p class="help-block text-danger"></p>
    </div>
</div>
<div class="row control-group">
    <div class="form-group col-xs-12 floating-label-form-group controls">
        <label>Phone Number</label>
        <input type="tel" class="form-control" placeholder="Phone Number" id="phone" required data-validation-required-message="Please enter your phone number.">
        <p class="help-block text-danger"></p>
    </div>
</div>
<div class="row control-group">
    <div class="form-group col-xs-12 floating-label-form-group controls">
        <label>Message</label>
        <textarea rows="5" class="form-control" placeholder="Message" id="message" required data-validation-required-message="Please enter a message."></textarea>
        <p class="help-block text-danger"></p>
    </div>
</div>
<div class="row control-group">
    <div class="form-group col-xs-12 floating-label-form-group controls">
        <label>Human</label>
        <input type="text" class="form-control" placeholder="2 + 3 = ?" id="human" required data-validation-required-message="Please solve math equation to prove you are human">
        <p class="help-block text-danger"></p>
    </div>
</div>
 <br>
<div id="success"></div>
<div class="row">
    <div class="form-group col-xs-12">
        <button type="submit" class="btn btn-success btn-lg">Send</button>
    </div>
</div>
</form>

Contact_me.js代码:

<?php
// Check for empty fields
if(empty($_POST['name'])        ||
empty($_POST['email'])      ||
empty($_POST['phone'])      ||
empty($_POST['message'])    ||
empty($_POST['human'])  ||
!filter_var($_POST['email'],FILTER_VALIDATE_EMAIL))
{
echo "No arguments Provided!";
return false;
}

//Check if simple anti-bot test is correct
if ($human !== 5) {
   $errHuman = 'Your anti-spam is incorrect';
}   

$name = $_POST['name'];
$email_address = $_POST['email'];
$phone = $_POST['phone'];
$message = $_POST['message'];
$message = $_POST['human'];

// Create the email and send the message
$to = 'info@mysite.com'; // Add your email address inbetween the '' replacing yourname@yourdomain.com - This is where the form will send a message to.
$email_subject = "Portfolio Website Message:  $name";
$email_body = "You have received a new message from your portfolio website contact form.\n\n"."Here are the details:\n\nName: $name\n\nEmail: $email_address\n\nPhone: $phone\n\nMessage:\n$message";
$headers = "From: noreply@mysite.com\n"; // This is the email address the generated message will be from. We recommend using something like noreply@yourdomain.com.
$headers .= "Reply-To: $email_address"; 
mail($to,$email_subject,$email_body,$headers);
return true;            
?>

jqBootstrapValidation.js是一个用于在Bootstrap表单上自动验证的插件,位于:http://ReactiveRaven.github.com/jqBootstrapValidation/

2 个答案:

答案 0 :(得分:0)

要阻止PHP发送邮件,您需要在调用脚本之前退出脚本。从您的代码中可以看出

if ($human !== 5) {
    $errHuman = 'Your anti-spam is incorrect';
}  

是您被告知数学答案是否正确的地方。所以你需要用以下代码替换它:

if ($_POST['human'] != 5) {
    $errHuman = 'Your anti-spam is incorrect';
    return false;
}

修改

首先将die($_POST['human']);添加到您的php(无论在哪里)。

然后在您的jquery中将data参数添加到successerror函数中。后跟console.log(数据);喜欢:

function(data) { 
    console.log("Success: "+data);
    ...

请分别更改"Success: "

完成这些编辑后,请运行它并查看日志。

答案 1 :(得分:0)

在html表单中,我看不到名称的字段,但它在php代码和javascript中都被引用。为了测试,我将此字段添加到我的表单版本中。下面的代码基于您的原始代码,除了发送实际邮件(没有本地邮件服务器!)之外,它按预期处理提交。但是,在几个地方你回显消息然后返回false - javascript是否使用这个回显的内容?

<?php

    session_start();/* required if using session based captcha image */

    /* If the page is accessed by GET etc then display error, otherwise process form input */
    if( $_SERVER['REQUEST_METHOD']=='POST' ){


        function message( $message=false, $errors=array() ){
            if( $message ) return json_encode( array( 'message' => $message, 'errors'=>$errors ) );
        }

        $errors=array();
        $options = array( 'flags' => FILTER_FLAG_STRIP_HIGH | FILTER_FLAG_ENCODE_HIGH );


        /* Filter all submitted fields */
        foreach( $_POST as $field => $value ){
            switch( $field ){
                case 'name': $name=filter_input( INPUT_POST, $field, FILTER_SANITIZE_SPECIAL_CHARS, $options ); break;
                case 'email': $email=filter_input( INPUT_POST, $field, FILTER_VALIDATE_EMAIL ); break;
                case 'phone': $phone=filter_var( filter_input( INPUT_POST, $field, FILTER_SANITIZE_NUMBER_FLOAT ), FILTER_VALIDATE_FLOAT ); break;
                case 'message': $message=filter_input( INPUT_POST, $field, FILTER_SANITIZE_SPECIAL_CHARS, $options ); break;
                case 'human': $human=filter_var( filter_input( INPUT_POST, $field, FILTER_SANITIZE_NUMBER_INT ), FILTER_VALIDATE_INT ); break;
                default:
                    $errors[]='Unknown field: '.$field;
                break;
            }
        }

        /* check each value is acceptable / has a value */
        $variables=array($name,$email,$phone,$message,$human);
        foreach( $variables as $value ){
            if( !isset( $value ) or empty( $value ) ){
                $errors[]='Missing parameter';
            }
        }

        /* Integer test */
        if( floatval( $human )!==floatval( $_SESSION['simple_maths_captcha'] ) ) {
            $errors[]='Anti-Spam verification failed';
        }

        if( !empty( $errors ) ) exit( message( 'Unable to send email', $errors ) );


        $to = 'info@mysite.com';
        $email_subject = "Portfolio Website Message: " . $name;
        $email_body = "You have received a new message from your portfolio website contact form.\n\n
            Here are the details:\n\n
            Name: ".$name."\n\n
            Email: ".$email_address."\n\n
            Phone:".$phone."\n\n
            Message:\n".$message;
        $headers = "From: noreply@mysite.com\n";
        $headers .= "Reply-To: ".$email_address; 

        /* should return either true or false */
        $result = @mail( $to, $email_subject, $email_body, $headers );


        exit( message( 'Your message has been sent: '.$result, $errors ) );


    } else {
        header( 'HTTP/1.0 405 Method Not Allowed', TRUE, 405 );
        $errors[]='Incorrect method';
        exit( message( 'Method not allowed', $errors ) );
    }         
?>

我还注意到你的javascript代码中有这一行: -

var human = $("textarea#human").val();

由于输入类型是标准文本字段,我不知道它是否会有任何区别,但这应该是: -

var human = $("input#human").val();

关于实际的验证码挑战,除非这个数字发生变化,否则它几乎不会给垃圾邮件发送者带来任何保护。通常,人们会(或者至少我)使用PHP来创建包含挑战难题的图像并设置会话变量,然后在提交表单后对其进行测试 - 因此每次都不同。

例如

<?php
    /* captcha.php */
    session_start();
    header('Content-type: image/png');



    function challenge( $full=false, $low1=1, $high1=20, $low2=1, $high2=20 ){
        /* Generate an arithmetic challenge with random numbers and a random method */
        $ops=array( '+','-' );
        if( $full==true ) $ops=array_merge( $ops, array( '/', 'x' ) );

        $numbers=array( rand( $low1, $high1 ), rand( $low2, $high2 ) );
        rsort( $numbers, SORT_NUMERIC );
        $key=rand( 0, count( $ops )-1 );

        $question="{$numbers[0]} {$ops[ $key ]} {$numbers[1]}";

        switch( $ops[ $key ] ){
            case '+': $answer=( $numbers[0] + $numbers[1] ); break;
            case '-': $answer=( $numbers[0] - $numbers[1] ); break;
            case '/': $answer=( $numbers[0] / $numbers[1] ); break;
            case 'x': $answer=( $numbers[0] * $numbers[1] ); break;
        }
        $obj=new stdClass;
        $obj->question=$question;
        $obj->answer=$answer;

        return $obj;
    }

    /* Calculate question and answer */
    $captcha=call_user_func( 'challenge', false, 1, 50, 1, 30 );
    $question=$captcha->question;
    $answer=$captcha->answer;

    /* Set the session variable that will be tested for */
    $_SESSION['simple_maths_captcha']=$answer;

    /* Render an image with this challenge */
    $oImg = @imagecreate( 80, 30 ) or die("unable to create image");
    $background = imagecolorallocate( $oImg, 255, 255, 255 );
    $colour = imagecolorallocate( $oImg, 0, 0, 0 );

    imagestring( $oImg, 4, 5, 5,  $question, $colour );
    imagepng( $oImg );
    imagedestroy( $oImg );
?>

如果您将上述代码保存为“captcha.php”,则可以使用标准图片代码在html中引用该图片。

<img src='captcha.php' alt='' width=80 height=30 />

(或者,使用.htaccess文件中的重写规则,类似于以下内容 你可以把它称为标准png图像。有经验的编码员可能会将此识别为php生成的图像,但是......)

htaccess rewrite
----------------
RewriteRule ^images/maths\.png$ /captcha.php [NC,L]

<img src='/images/maths.png' alt='' width=80 height=30 />

在你的html中,你仍然需要文本输入字段来接收答案,将图像添加到表单中的适当位置,然后在php中测试正确的答案。所以,而不是: -

    if( intval( $human )!==5 ) {
        echo 'Anti-Spam verification failed';
        return false;
    }

你可以这样测试: -

    if( floatval( $human )!==floatval( $_SESSION['simple_maths_captcha'] ) ) {
        echo 'Anti-Spam verification failed';
        return false;
    }

我注意到在jqBootstrapValidation.js代码中,ajax函数的数据类型设置为json,回调函数有一个数据参数。我更改了上面的代码,如果有错误则返回json,如果表单处理正常则返回json成功消息。我不使用jQuery所以也许我误解了javascript代码,但我想知道回调是否期望来自表单处理的json编码响应?毫无疑问,精通jQuery的人可以回答这个问题。