我试图使用fetch POST一个JSON对象。

根据我的理解,我需要将一个字符串化的对象附加到请求的主体,例如:

fetch("/echo/json/",
{
    headers: {
      'Accept': 'application/json',
      'Content-Type': 'application/json'
    },
    method: "POST",
    body: JSON.stringify({a: 1, b: 2})
})
.then(function(res){ console.log(res) })
.catch(function(res){ console.log(res) })

当使用jsfiddle的JSON回显时,我希望看到我发送的对象({a: 1, b: 2})回来,但这不会发生- chrome devtools甚至不显示JSON作为请求的一部分,这意味着它没有被发送。


当前回答

上面的答案对PHP7不起作用,因为它有错误的编码,但我可以用其他答案找出正确的编码。这段代码还发送验证cookie,这可能是你在处理PHP论坛时需要的:

julia = function(juliacode) {
    fetch('julia.php', {
        method: "POST",
        credentials: "include", // send cookies
        headers: {
            'Accept': 'application/json, text/plain, */*',
            //'Content-Type': 'application/json'
            "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8" // otherwise $_POST is empty
        },
        body: "juliacode=" + encodeURIComponent(juliacode)
    })
    .then(function(response) {
        return response.json(); // .text();
    })
    .then(function(myJson) {
        console.log(myJson);
    });
}

其他回答

你可以用await/async做得更好。

http请求参数:

const _url = 'https://jsonplaceholder.typicode.com/posts';
let _body = JSON.stringify({
  title: 'foo',
  body: 'bar',
  userId: 1,
});
  const _headers = {
  'Content-type': 'application/json; charset=UTF-8',
};
const _options = { method: 'POST', headers: _headers, body: _body };

使用干净的async/await语法:

const response = await fetch(_url, _options);
if (response.status >= 200 && response.status <= 204) {
  let data = await response.json();
  console.log(data);
} else {
  console.log(`something wrong, the server code: ${response.status}`);
}

使用老式fetch().then().then():

fetch(_url, _options)
  .then((res) => res.json())
  .then((json) => console.log(json));

它可能对某些人有用:

我遇到的问题是,formdata没有为我的请求发送

在我的案例中,是以下标题的组合也导致了这个问题和错误的Content-Type。

我和请求一起发送了这两个头文件当我删除了工作的头文件时它并没有发送formdata。

"X-Prototype-Version": "1.6.1", "X-Requested-With": "XMLHttpRequest"

另外,其他答案表明,Content-Type头需要正确。

对于我的请求,正确的Content-Type头是:

“内容类型”:“应用程序/ x-www-form-urlencoded;charset = utf - 8”

所以底线是,如果你的formdata没有附加到Request,那么它可能是你的header。试着减少标题,然后一个一个地添加它们,看看你的问题是否得到解决。

有同样的问题-没有身体从客户端发送到服务器。 添加内容类型头为我解决了这个问题:

var headers = new Headers();

headers.append('Accept', 'application/json'); // This one is enough for GET requests
headers.append('Content-Type', 'application/json'); // This one sends body

return fetch('/some/endpoint', {
    method: 'POST',
    mode: 'same-origin',
    credentials: 'include',
    redirect: 'follow',
    headers: headers,
    body: JSON.stringify({
        name: 'John',
        surname: 'Doe'
    }),
}).then(resp => {
    ...
}).catch(err => {
   ...
})

您可以使用fill-fetch,这是fetch的扩展。简单地说,你可以像下面这样发布数据:

import { fill } from 'fill-fetch';

const fetcher = fill();

fetcher.config.timeout = 3000;
fetcher.config.maxConcurrence = 10;
fetcher.config.baseURL = 'http://www.github.com';

const res = await fetcher.post('/', { a: 1 }, {
    headers: {
        'bearer': '1234'
    }
});

我认为,我们不需要将JSON对象解析为字符串,如果远程服务器接受JSON到他们的请求,只需运行:

const request = await fetch ('/echo/json', {
  headers: {
    'Content-type': 'application/json'
  },
  method: 'POST',
  body: { a: 1, b: 2 }
});

比如curl请求

curl -v -X POST -H 'Content-Type: application/json' -d '@data.json' '/echo/json'

如果远程服务不接受json文件作为主体,只需发送一个dataForm:

const data =  new FormData ();
data.append ('a', 1);
data.append ('b', 2);

const request = await fetch ('/echo/form', {
  headers: {
    'Content-type': 'application/x-www-form-urlencoded'
  },
  method: 'POST',
  body: data
});

比如curl请求

curl -v -X POST -H 'Content-type: application/x-www-form-urlencoded' -d '@data.txt' '/echo/form'