PHP 从 Ajax 调用接收空的 $_POST 变量

Posted

技术标签:

【中文标题】PHP 从 Ajax 调用接收空的 $_POST 变量【英文标题】:PHP receives empty $_POST variables from Ajax call 【发布时间】:2017-03-18 21:51:16 【问题描述】:

我正在尝试使用 AJAX 调用将表单数据发送到 php 脚本。我正在序列化表单数据并通过 POST 方法将其作为 JSON 变量发送到 PHP 脚本。 Ajax 数据变量似乎是正确的,但由于某种原因 PHP $_POST 数组为空,我很难理解我在这里做错了什么。

这是我的 ajax 调用

// AJAX
        var input_data = $('#contact-form').serialize(); 

        event.preventDefault();

        $.ajax(
            url: 'contact.php',
            type:'POST',
            dataType:'json',//return type from server side function [return it as JSON object]
            contentType: "application/json",
            data: input_data, //Pass the data to the function on server side
            success: function (data)  //Array of data returned from server side function

                $.each(data,function(index)
                    alert(data[index]); // used for debugging, returns 1
                );
            

        );

        alert("called");
        if(input_data.length < 1)
        
            alert("empty");
            alert(input_data);
        
        else
        
            alert("not empty");
            alert(input_data);
        
        return false; 

表格

<form class="text-center" id="contact-form" method="POST" action="contact.php">
                    <div class="form-group">
                        <input type="text" class="form-control" id="name" name="name" placeholder="Name">
                    </div>
                    <div class="form-group">
                        <input type="email" class="form-control" id="email" name="email" placeholder="Email">
                    </div>
                    <div class="form-group">
                        <textarea class="form-control" rows="5" id="msg" name="msg" placeholder="Type your message"></textarea>
                    </div>
                    <div class="form-group">
                        <div class="g-recaptcha buffer" data-sitekey="some_key" data-callback="recaptcha_callback"></div>
                        <input type="hidden" class="hiddenRecaptcha required" name="hiddenRecaptcha" id="hiddenRecaptcha">
                    </div>


                    <button type="submit" class="btn btn-lg btn-primary text-uppercase buffer">Send message</button>
                </form>

最后是我的contact.php脚本

<?php
    header('Content-Type: application/json');

    $name;
    $email;
    $msg;

    $nameErr = $emailErr = $msgErr = 0;

    if ($_SERVER["REQUEST_METHOD"] == "POST") 
        if (empty($_POST["name"])) 
            $nameErr = 1;
        
        else 
            $name = $_POST["name"];
            $nameErr = 0;
        

        if (empty($_POST["email"])) 
            $emailErr = 1;
        
        else 
            $email = $_POST["email"];
            if (!filter_var($email, FILTER_VALIDATE_EMAIL) === false) 
                $emailErr = 0;
             else 
                $emailErr = 1;
            
        

        if (empty($_POST["msg"]))  
            $msgErr = 1;
        
        else 
            $msg = $_POST["msg"];
            $msgErr = 0;
        

        if($nameErr == 0 && $emailErr == 0 && $msgErr == 0)
        
            $to = "example@example.com";
            $subject = 'Contact request - site';
            $txt = $_POST['msg'];
            $headers = "From: " . $_POST['email'] . "\r\n";
            mail($to,$subject,$txt,$headers);
            echo json_encode(array("sent"));
        
        else
        
            echo json_encode(array($nameErr, $emailErr, $msgErr));
        
    
    else
    
        echo json_encode(array("post_error"));
    

?>

通过运行 PHP 代码,电子邮件可以正确发送。使用 Ajax 调用时,$_POST 数组为空,它从 PHP 代码中的最后一个 if 语句返回三个错误代码。此外,如果有更好的方法来实现这一点,我会很高兴看到替代方案。感谢您的帮助,谢谢。

编辑:JSON 数据

【问题讨论】:

首先,如果您使用 jQuery,为什么不直接使用 $.post() 而不是 $.ajax()?其次,$_POST 变量应该出现在 PHP 文件中 - 在 PHP 文件的开头添加 var_dump($_POST) @junkfoodjunkie $.post$.ajax 的别名,类型为POST,无需更改。 这不是必需的,它只是当您已经执行 POST 时更简洁的方法,并且您不需要执行任何 X-HTTP 请求。 $.post('contact.php', $('#formID').serialize(),function(data) 我试过了,它返回了一个空数组。从表单操作调用 PHP 脚本按预期工作。我想我明天就从头开始重写它,它可能很简单,我可以看到它。这次我将使用 jQuery $.post() 来看看它是如何工作的。 您告诉网络服务器您正在发送 JSON,但实际上您发送的是常规 HTTP 查询字符串 - 因为它是 JSON,PHP 没有将 POST 变量解析为 $_POST。随着contentType: "application/json", 的删除,jQuery 告诉网络服务器“我发送application/x-www-form-urlencoded 数据”并使PHP 将POST 参数解析为$_POST 【参考方案1】:

通过使用$('#contact-form').serialize(),您可以让 jQuery 将常规字段中的数据转换为 HTTP 查询字符串 key=val&amp;key2=val2&amp;... - 但是现在您在 $.ajax 中设置 contentTypeapplication/json,这使得 jQuery 设置了一个 HTTP请求的标头Content-Type: application/json。 jQuery 不会抱怨它可能是错误的 Content-Type - 你应该最了解它。

由于 POST-Request 具有 Content-Type application/json,PHP 不会将 HTTP POST 数据解析为超全局 $_POST。相反,您必须从 php://input 读取原始 POST 数据。

您现在的问题是,您告诉 HTTP POST 数据是 JSON,但您发送的实际上不是 JSON - 它是一个 HTTP 查询字符串。由于它是一个 HTTP 查询字符串,您可以从您的 $.ajax 调用中删除 contentType: "application/json",,这将使 jQuery 设置正确的 Content-Type 标头。

jQuery 会将 Content-Type 标头设置为 application/x-www-form-urlencoded - 这是适合您的正确 Content-Type 标头。由于这是 PHP 解析的 Content-Type 之一,HTTP POST 数据现在可以在超全局 $_POST 中使用。

$_POST 只会填充特定的 Content-Type,即 multipart/form-dataapplication/x-www-form-urlencoded。如果 HTTP Content-Type 两者都不是,$_POST 将不会被填充,您必须从php://input 读取 RAW POST 数据。

http://php.net/manual/en/reserved.variables.post.php

【讨论】:

那么,沿着这些路线的东西会起作用吗? $str_json = file_get_contents('php://input'); $str_json = json_decode($str_json); 呃,什么?那是大错特错。 $_POST 接收任何类型的 $_POST 变量,即使通过 AJAX,只要您没有文件,就无需将其编码为多部分。 @Petar-Krešimir 如果你真的发送 JSON,是的,它应该可以工作。 我的意思是,您发布的内容类型无关紧要 - PHP 仍会收到所有 $_POST 变量。当然,如果您设置的内容类型是特殊的,这可能很重要,但是常规的内容类型 text/html 可以正常工作。 $_POST 包含 POST 变量,即使您使用 text/html 作为内容类型。我怎么知道?我在编写网站时每天都使用它。并且 $HTTP_RAW_POST_DATA 现在已被多个 PHP 版本弃用。抱歉:标记@CharlotteDunois

以上是关于PHP 从 Ajax 调用接收空的 $_POST 变量的主要内容,如果未能解决你的问题,请参考以下文章

Php没有通过$ _POST接收变量

Ajax调用第三方接口;ICP备案查询;PHP后台调用接口;Js调用第三方接口;Ajax+PHP接口开发;

Ajax调用第三方接口;ICP备案查询;PHP后台调用接口;Js调用第三方接口;Ajax+PHP接口开发;

Ajax调用第三方接口;ICP备案查询;PHP后台调用接口;Js调用第三方接口;Ajax+PHP接口开发;

能够使用 $_GET 但不能接收数据 $_POST [重复]

Ajax、PHP、SQL 和 JavaScript