具有contentType:';的Ajax调用;application/json';不起作用


Ajax call with contentType: 'application/json' not working

我有一个ajax调用,它将表单数据发送到php函数。由于我读了很多关于使用contentType: 'application/json'是最佳实践的文章,我也想试一试。但不幸的是,当我使用它时,我的脚本没有返回任何内容。如果我删除它,脚本就会做它应该做的事情。

你知道原因是什么吗?为什么?非常感谢。

$('#Form').submit(function(e) {
            e.preventDefault();
            var content = $(this).serialize() + "&ajax=1";
            $.ajax('app/class/controller/contactForm.php', {
              type: "POST",
              //contentType: 'application/json',
              dataType: 'json',
              data: content,
              success: function(result) {
                  console.log(result);
              }
            });
        })

和我的PHP:

if(isset($_POST['ajax']) && $_POST['ajax'] === '1') {
    echo json_encode(validateForm($_POST));
}

使用contentType: 'application/json'时,将无法依赖于正在填充的$_POST$_POST仅为表单编码的内容类型填充。

因此,您需要从PHP原始输入中读取数据,如下所示:

$input = file_get_contents('php://input');
$object = json_decode($input);

当然,如果您想发送application/json,实际上应该发送JSON,而您并没有这样做。您要么需要直接将对象序列化为JSON,要么需要执行类似的操作-使用jQuery将表单数据转换为JavaScript对象-从表单序列化对象。

老实说,在您的情况下,由于您处理的是表单数据,我不太认为存在使用application/json的用例。

您提到的最佳实践是关于服务器脚本将JSON的Content-Type设置为"application/JSON":

Header('Content-Type: application/json; charset=UTF8');

这是因为,否则将发送一个默认的Content-Type,通常是一个包罗万象的text/html,这可能会导致客户端无法理解。

如果您不在jQuery请求中为自己指定内容类型,jQuery将确定最合适的内容类型。这里的问题是,您发送了一个POST表单,jQuery为其设置的默认Content-Typeapplication/x-www-form-urlencoded,这告诉PHP将数据解码为POST字段并填充$_POST。然后,您的脚本将从$_POST(或者$_REQUEST)中恢复其参数。

通过将其更改为application/json$_POST将不再被填充,接收脚本操作将不会接收到预期的参数,并且操作将中断。

所以你要么需要:

  • 不要自己指定内容类型(最好是IMHO)
  • 将内容类型设置为application/x-www-form-urlencoded; charset=UTF-8
  • 设置内容类型CCD_ 18,修改脚本解析POST流并解码JSON数据;看看这个答案

第三个选项要求正确处理php://input

PHP脚本应该设置Content-Type头。

if(isset($_POST['ajax']) && $_POST['ajax'] === '1') {
    header('Content-Type: application/json');
    echo json_encode(validateForm($_POST));
}