POST 适用于 JQuery,但不适用于 XMLHttpRequest

2022-01-15 00:00:00 post xmlhttprequest jquery javascript

所以我正在尝试从 Javascript 发布到我的服务器 (php),并且尝试不使用 JQuery.

So I'm trying to POST to my server (php) from Javascript and am trying to not use JQuery.

此代码工作并将必要的数据发布到数据库

This code works and posts the necessary data to the database

var msg = {};
msg['name'] = 'joe';
msg['message'] = 'why no work';

$.post(phpURL, msg, function(data) {});

但这个没有

var xhr = new XMLHttpRequest();
xhr.open("POST", phpURL, true);
xhr.send(msg);

我什至查看了我的 php 日志,查看了标题,我能看到的 JQuery 与 XHR 的唯一区别是内容类型标题 "application/x-www-form-urlencoded;charset=UTF-8" 和这个头 "x-requested-with"XMLHttpRequest".

I even looked at my php logs, looked at the headers and the only difference of the JQuery one from the XHR one I could see was the content-type header "application/x-www-form-urlencoded; charset=UTF-8" and this header "x-requested-with" "XMLHttpRequest".

所以我尝试了以下标题的所有组合.

So I tried all combinations of the following headers.

var xhr = new XMLHttpRequest();
xhr.open("POST", phpURL, true);
//xhr.setRequestHeader('Content-Type', 'application/json');
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
//xhr.setRequestHeader('x-requested-with', 'XMLHttpRequest');
xhr.send(msg);

没有效果.

值得一提的是,如果我尝试在任何地方添加 JSON.stringify(msg),它不起作用,无论是在 JQuery 还是 XHR 中.但我想先让这个工作,并解释这个奇怪的差异.

It is worth mentioning if I try to add JSON.stringify(msg) anywhere, it does not work, neither in JQuery or XHR. But I would like to get this working first, and explain this bizarre difference.

我倾向于认为这是一个 Javascript 问题,因为 JQuery 帖子有效,此外,服务器的 GET 请求和我尝试发布到的同一个表也有效.

I am inclined to believe this is a Javascript issue since the JQuery post works and in addition, a GET request of the server and the same table I'm trying to post to does work.

推荐答案

不要将 JavaScript 对象与 JSON 混淆.

如果您将对象传递给 jQuery 的 data 参数,那么它会将其编码为 application/x-www-form-urlencoded 数据(不是 JSON!).

If you pass an object to jQuery's data parameter then it will encode it as application/x-www-form-urlencoded data (not JSON!).

如果您将 application/x-www-form-urlencoded 数据发布到 PHP,那么它将解析它并用它填充 $_POST 超全局.

If you POST application/x-www-form-urlencoded data to PHP then it will parse it and populate the $_POST superglobal with it.

如果您将对象传递给 XMLHttpRequest 对象的 send() 方法,那么它将不为您编码.它会隐式调用 .toString() 并发送任何有用的东西.

If you pass an object to the send() method of an XMLHttpRequest object then it will not encode it for you. It will invoke .toString() on it implicit and send nothing very useful at all.

要达到与 jQuery 相同的效果,您需要 自己编码数据.不要忘记同时设置 Content-Type 标头!

To achieve the same effect as jQuery will do then you need to encode the data yourself. Don't forget to also set the Content-Type header!

const encoded = new URLSearchParams(Object.entries(msg)).toString();
const xhr = new XMLHttpRequest();
xhr.open("POST", phpURL, true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.send(encoded);


如果您想发送 JSON,那么您还必须对其进行编码,但这只需使用 JSON.stringify() 虽然您还需要设置 Content-Type 标头(到 application/json 这次).

const encoded = JSON.stringify(msg);
const xhr = new XMLHttpRequest();
xhr.open("POST", phpURL, true);
xhr.setRequestHeader("Content-Type", "application/json");
xhr.send(encoded);

但是,PHP 不会自动解析 JSON,因此 $_POST 将保持为空,因此您 需要手动解析.

However, PHP will not parse JSON automatically so $_POST will remain empty, so you need to parse it manually.

<?php 
    $json = file_get_contents('php://input');
    $msg = json_decode($json);

相关文章