【问题标题】:POST contact form missing data when special character is used使用特殊字符时 POST 联系表单缺少数据
【发布时间】:2018-12-03 19:35:19
【问题描述】:

我正在使用一个简单的联系表格:http://luiszuno.com/previews/formy/ 问题是,每当在表单上输入字符“&”时,电子邮件中都不会收到“&”之后的其余消息。编辑:添加了代码,除了缺少数据问题外,表单可以正常工作。什么可能导致此问题?

    jQuery(document).ready(function($) {

    $("#formy").on( "submit", function( event ) {
        $(this).serialize();
    });
    // Hide messages 
    $("#formy-success").hide();
    $("#formy-error").hide();
    $("input,textarea").blur(function(){
            $(this).css("border-color","#596a87");
        });

    // on submit...
    $("#formy #submit").click(function() {

        $(this).serialize();

        // Required fields:

        //name
        var name = $("#name").val();
        if(name == "" || name == "Name *"){
            $("#name").focus();
            $("#formy-error").fadeIn().text("Name required");
            $("#name").css("border-color","#a22528");
            return false;   
        }
        else {$("#name").css("border-color","#596a87");}


        // email

        var email = $("#email").val();
        if(email == "" || email == "Email *"){
            $("#email").focus();
            $("#formy-error").fadeIn().text("Email required");
            $("#email").css("border-color","#a22528");
            return false;
        }
        else {$("#email").css("border-color","#596a87");}

        // email validation
        function validateEmail(email) {
            var filter = /^([a-zA-Z0-9_.+-])+\@(([a-zA-Z0-9-])+\.)+([a-zA-Z0-9]{2,4})+$/;
            return filter.test(email);
        }
        if (!validateEmail(email)) {
            $("#formy-error").fadeIn().text("Invalid email address");
            $("#email").css("border-color","#a22528");
            return false;
        }

        //budget
        var budget = $("#budget").val();
        if(budget == "" || budget == "Budget"){
            return false;
        }


        // comments
        var comments = $("#comments").val();
        if(comments == "" || comments == "Message *"){
            $("#comments").focus();
            $("#formy-error").fadeIn().text("Message required");
            $("#comments").css("border-color","#a22528");
            return false;
        }
        else {$("#comments").css("border-color","#596a87");}

        // send mail php
        var sendMailUrl = $("#sendMailUrl").val();

        // Retrieve values for to, from & subject at the form
        var to = $("#to").val();
        var from = $("#from").val();
        var subject = $("#subject").val();

        // Create the data string
        var dataString = 'name=' + name
                        + '&email=' + email        
                        + '&comments=' + comments
                        + '&to=' + to
                        + '&from=' + from
                        + '&budget=' + budget   
                        + '&subject=' + subject;                             
        // ajax 
        $.ajax({
            type:"POST",
            url: sendMailUrl,
            data: dataString,
            success: success()
        });
    });  


    // On success...
     function success(){
        $("#formy-success").fadeIn(250).text("Thanks, I will contact you soon!");
        $("#formy-error").hide();
        $("#formy fieldset").slideUp(250);
     }

    return false;
});

发送邮件.php

    <?php header("Content-Type: text/html; charset=utf-8"); 


//vars
$subject = $_POST['subject'];
$to = explode(',', $_POST['to'] );

$from = $_POST['email'];

//data
$msg = "NAME: "  .$_POST['name']    ."<br>\n";
$msg .= "EMAIL: "  .$_POST['email']    ."<br>\n";
$msg .= "BUDGET: "  .$_POST['budget']    ."<br>\n";
$msg .= "COMMENTS: "  .$_POST['comments']    ."<br>\n";

//Headers
$headers  = "MIME-Version: 1.0\r\n";
$headers .= "Content-type: text/html; charset=UTF-8\r\n";
$headers .= "From: <".$from. ">" ;


//send for each mail
foreach($to as $mail){
   mail($mail, $subject, $msg, $headers);
}

?>

【问题讨论】:

  • 链接在这里不起作用。请添加一个 sn-p 或关闭为 no minimal reproducible example
  • 好吧,我们看不到您的代码,因此很难说太多,除了我怀疑您可能没有对表单数据进行 URI 编码。 & 是查询字符串和 POST 数据字符串中的特殊字符 - 它用于表示下一个参数的开始
  • 好吧,就像我说的,你需要对数据进行 URIencode。通常,如果您只是告诉 jQuery 序列化您的表单,或者为它提供一个包含您的数据的 JavaScript 对象,那么它会自动为您进行编码。大概您正在手动构建输入数据或其他东西。问题在于您的客户端代码而不是您的 PHP。问题在于发送到服务器的内容,而不是服务器到达时对其进行的处理。
  • @ADyson 我的 jQuery 在 index.php 文件中,而不是在联系表单上,我还能使用序列化吗?不确定如何使用 URIencode 在 $_POST 之前自动处理整个输入字段。 htmlspecialchars也可以用吗?
  • “我的 jQuery 在 index.php 文件上,而不是在联系表单上”......不知道你的意思。一旦 jQuery 代码被加载到页面中,它的来源就无关紧要了。如果您使用 jQuery/AJAX 提交表单并且代码正在处理表单的提交,那么您可以序列化表单。因此,请向我们展示表单以及您当前用于提交表单的代码。您可以将上面的所有 PHP 删除,它不相关。

标签: php jquery character contact-form


【解决方案1】:

按照@ADyson 的建议使用 encodeURIComponent() 来修复使用联系表单时收到的电子邮件中丢失的数据/网址。

var comments = $("#comments").val();
var e_comments = encodeURIComponent(comments);

【讨论】:

    【解决方案2】:

    您的问题是您正在手动构建数据字符串,而不是对插入到字符串中的数据值进行 URI 编码。因此,文本中的任何原始 &amp; 字符都将被假定为 URI 的一部分而不是数据,这意味着它将被解释为指示下一个参数的开始,而不仅仅是文本中的一个字符。对这些数据进行 URI 编码会将这个和其他特殊字符转换为它们的编码等效项,因此它们不会被误解。

    现在,您当然可以通过使用 encodeURIComponent() 包装每个字段变量来解决此问题,但这是冗长乏味的:

    var dataString = 'name=' + encodeURIComponent(name)
                            + '&email=' + encodeURIComponent(email)        
                            + '&comments=' + encodeURIComponent(comments)
                            + '&to=' + encodeURIComponent(to)
                            + '&from=' + encodeURIComponent(from)
                            + '&budget=' + encodeURIComponent(budget)   
                            + '&subject=' + encodeURIComponent(subject); 
    

    有更好的方法:

    目前,您的$(this).serialize(); 将不起作用,因为this 代表单击的按钮,而不是表单。但是,如果您将其指向表单,您可以使用它轻松地自动序列化其中的字段,并且 jQuery 将代表您处理任何编码问题。这节省了手动编码和单独获取每个字段值的代码(尽管我注意到您目前需要这个来进行验证,尽管还有其他实现验证的方法可以消除这种需要,但这完全是另一个话题)。

    $.ajax({
        type:"POST",
        url: sendMailUrl,
        data: $("#formy").serialize(),
        success: success //Unrelated: I also removed the brackets here, so it becomes a _reference_ to the "success" function - writing success() as you did means the function is immediately executed, and what gets passed to jQuery is the _result_ of the function, which isn't what you want in this case
    });
    

    如您所见,这不那么麻烦了。而且,如果您将来在表单中添加更多字段,则根本不需要更改这部分代码。


    另外一点 - 使用 JavaScript 验证表单输入会遇到很多麻烦。这很好并且用户友好,但它不提供任何安全性。在服务器端,您似乎很乐意将浏览器直接发送的任何值插入到您的电子邮件中。任何具有少量知识的用户都可以使用他们的开发工具修改您的 JavaScript,或者关闭 JS,或者完全使用其他工具(例如 PostMan,或自定义应用程序)在您的服务器上触发 HTTP 请求,而无需接触您的表单.他们可能会发送有问题的值,这可能会搞砸您的电子邮件 - 例如一个不同的“from”值,或者一些讨厌的 HTML,或者如果你在应用程序的任何地方与数据库交互,执行 SQL 注入攻击来搞砸。您应该始终验证 PHP 代码中的所有传入数据是否存在安全问题,并确保其符合您的业务规则,然后再将其用于其他任何事情。

    【讨论】:

      猜你喜欢
      • 2023-03-29
      • 1970-01-01
      • 2018-10-02
      • 2018-06-15
      • 2013-04-08
      • 1970-01-01
      • 2014-01-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多