Ecmascript 6 使用fetch发送非字符串化对象

Ecmascript 6 使用fetch发送非字符串化对象,ecmascript-6,es6-promise,form-data,fetch-api,Ecmascript 6,Es6 Promise,Form Data,Fetch Api,我是第一次使用fetchapi,在将非字符串化的JSON对象传递到服务器时遇到了问题。 基本上,我希望实现与此相同的行为: $.post(url, {"test": "test"}, function(response) { console.log(response); }); fetch方法正在与一个web API通信,这个API对我来说是不可用的,需要一个普通的JSON对象 通常我只使用FormData将数据传递给服务器,但是JSON将转换为字符串[Object]: 使用API使用的

我是第一次使用fetchapi,在将非字符串化的JSON对象传递到服务器时遇到了问题。 基本上,我希望实现与此相同的行为:

$.post(url, {"test": "test"}, function(response) {
   console.log(response);
});
fetch方法正在与一个web API通信,这个API对我来说是不可用的,需要一个普通的JSON对象

通常我只使用FormData将数据传递给服务器,但是JSON将转换为字符串[Object]:

使用API使用的$\u POST时,body请求似乎为空,但在使用file\u get\u contents时,body请求给出了正确的值php://input.

我认为这与请求的标题错误有关。因此,我尝试添加Ajax post使用的标题:content-type:multipart/form-data;。然而,这也没有得到任何价值

我想知道这是不是有意不使用纯JSON对象作为数据提供,或者我只是缺少了一些东西

这确实有效,但不允许,因为它是JSON对象的字符串化版本:


假设您的数据在变量var data={a:some data,b:123}中。如果希望PHP中的代码以这种方式访问这些字段:

$_POST["a"] == "some data";
$_POST["b"] == 123;
var fdata = new FormData();
fdata.append('a', 'some data');
fdata.append('b', '123');
然后,您需要通过以下方式以formData格式发送数据:

$_POST["a"] == "some data";
$_POST["b"] == 123;
var fdata = new FormData();
fdata.append('a', 'some data');
fdata.append('b', '123');
现在您可以发送该数据,PHP将有权访问单独的字段a和b,但请注意,b将是一个字符串,而不是一个数字

如果要发送数组,该怎么办。让我们说{c:['hello','world','!']}?必须遵循PHP名称约定并多次添加相同的名称:

var fdata = new FormData();
fdata.append('c[]', 'hello');
fdata.append('c[]', 'world');
fdata.append('c[]', '!');

设置表单数据实例后,可以将其用作请求主体。

因此,首先,我需要发布到post协议,该协议由$\u post使用。为此,我添加了application/x-www-form-urlencoded的头,该头是$\u POST使用的协议,如fetch POST请求中所述:

fetch(url, {
   headers: new Headers({'Content-Type': 'application/x-www-form-urlencoded'}), // Default header which $_POST listens to
   ...
现在,$.post实际发送数据的方式是创建一个序列化字符串,例如:给定对象的%5Bone%5D=1。要将对象转换为序列化字符串,可以使用:


这将使您能够像使用简单的$.POST一样从$\u POST检索数据。

您是否尝试过简单的body:JSON.stringifydata,因为JSON只是一个字符串值。它并不是一个真正的物体such@CodingIntrigue当我不使用formData时,它似乎无法与$\u POST一起使用。这就是为什么我认为fetch api在使用formData对象时会自动设置标题,但我不知道是哪个。呃,你的$.post片段也不发送JSON?@Bergi你的意思是{test:'test}应该变成{test:test}?更新内容如下:P@nkmol:否,我的意思是,$.post发送请求时默认内容类型为application/x-www-form-urlencoded。您的对象通过发送成为test=test,而不是通过JSON.stringify成为{test:test}。谢谢您的时间。但是,如上所述,手动创建FormData并不能使其像我所希望的那样动态。我找到了答案,将创造一个新的答案:我不理解你试图达到的活力水平。事实上,查询字符串解决方案更糟糕,因为它有长度限制,并且发送大量数据是不可行的。虽然您没有将URL编码字符串用作查询字符串,而是用作帖子正文,因此不应该有长度限制。是的,您是对的。它不是URL编码的字符串,而是序列化的字符串表示形式。改变了。所以动态性是,我不必担心对象本身内部的所有值。想象一下,拥有一个大对象,然后手动将每个变量放入FormData将是一件痛苦的事情。到目前为止,我在正文中使用$.param没有发现任何缺点。Downvoter,请让我知道这个答案有什么问题。
fetch(url, {
            headers: new Headers({'Content-Type': 'application/x-www-form-urlencoded'}), // Default header which $_POST listens to
            method: 'POST',
            body: $.param(data)
        })