首页 > 解决方案 > POST 适用于 JQuery,但不适用于 XMLHttpRequest

问题描述

所以我试图从 Javascript 发布到我的服务器(php),并试图不使用 JQuery。

此代码有效并将必要的数据发布到数据库

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 的唯一区别是 content-type header"application/x-www-form-urlencoded; charset=UTF-8"和 this header "x-requested-with" "XMLHttpRequest"

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

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 中。但我想先让这个工作,并解释这个奇怪的差异。

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

标签: javascriptjquerypostxmlhttprequest

解决方案


不要将 JavaScript 对象与 JSON 混淆

如果你将一个对象传递给 jQuery 的data参数,那么它将把它编码为application/x-www-form-urlencoded数据(不是 JSON!)。

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

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

要达到与 jQuery 相同的效果,您需要自己对数据进行编码。不要忘记也设置Content-Type标题!

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会一直为空,所以需要手动解析

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

推荐阅读