php 带有 contentType 的 Ajax 调用:'application/json' 不起作用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20295080/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 03:02:30  来源:igfitidea点击:

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

phpjqueryajaxjsoncontent-type

提问by Sebsemillia

I have an ajax call, that sends form data to a php function. Since I read a lot that using contentType: 'application/json'is best practice I wanted to give it a try as well. But unfortunately my script doesn't return anything when I use it. If I remove it, the script does what it is supposed to do.

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

Do you have any idea what the reason might be and why? Thank you!

您知道原因可能是什么吗?谢谢!

$('#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);
              }
            });
        })

and my PHP:

和我的 PHP:

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

回答by Mike Brant

When using contentType: 'application/json'you will not be able to rely on $_POSTbeing populated. $_POSTis only populated for form-encoded content types.

使用时,contentType: 'application/json'您将无法依赖$_POST被填充。 $_POST仅针对表单编码的内容类型填充。

As such, you need to read your data from PHP raw input like this:

因此,您需要像这样从 PHP 原始输入读取数据:

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

Of course if you want to send application/jsonyou should actually send JSON, which you are not doing. You either need to build the object serialization to JSON directly, or you need to do something like this - Convert form data to JavaScript object with jQuery- to serialize the object from the form.

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

Honestly in your case, since you are dealing with form data, I don't quite think the use case for using application/jsonis there.

老实说,在您的情况下,由于您正在处理表单数据,因此我不太认为 using 的用例在application/json那里。

回答by LSerni

The best practice you refer to is about the server scriptsetting the Content-Typefor JSON to "application/json":

您参考的最佳实践是关于Content-TypeJSON设置为“application/json”的服务器脚本

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

This is because otherwise a default Content-Typewill be sent, often a catch-all text/html, and this could lead to an incomprehension with the client.

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

If you do notspecify yourself a Content-Type in the jQuery request, jQuery will determine the most appropriate one. The problem here is that you were sending a POST form, for which the default Content-Typeset by jQueryis application/x-www-form-urlencoded, which tells PHP to decode the data as POST fields and populate $_POST. Your script would have then recovered its parameters from $_POST(or maybe $_REQUEST).

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

By changing it to application/json, $_POSTwill no longer be populated, the receiving script operation won't receive the parameters where it was expecting to, and the operation breaks.

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

So you either need to:

所以你要么需要:

  • not specify the Content-Type yourself (better, IMHO)
  • set a Content-Type of application/x-www-form-urlencoded; charset=UTF-8
  • set a Content-Type of application/json; charset=UTF-8and modify the script to parse the POST stream and decode the JSON data; see this answer.
  • 不要自己指定内容类型(更好,恕我直言)
  • 设置一个内容类型 application/x-www-form-urlencoded; charset=UTF-8
  • 设置 Content-Typeapplication/json; charset=UTF-8并修改脚本以解析 POST 流并解码 JSON 数据;看到这个答案

The third option requires proper handlingof php://input.

第三个选项需要妥善处理php://input

回答by ceejayoz

The PHP script should be setting the Content-Type header.

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

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