我试图使用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作为请求的一部分,这意味着它没有被发送。


当前回答

我认为你的问题是jsfiddle只能处理表单url编码的请求。但是让json请求的正确方法是将正确的json作为body传递:

fetch (https://httpbin.org/post, { 方法:“文章”, 标题:{ 'Accept': 'application/json, text/plain, */*', “内容类型”:“application / json” }, 身体:JSON。stringify({a: 7, str: 'Some string: &=&'}) })。然后res => res.json()) .then(res => console.log(res));

其他回答

从搜索引擎,我结束了这个主题的非json发布数据与fetch,所以我认为我将添加这个。

对于非json,你不必使用表单数据。你可以简单地设置Content-Type头为application/x-www-form-urlencoded,并使用一个字符串:

fetch('url here', {
    method: 'POST',
    headers: {'Content-Type':'application/x-www-form-urlencoded'}, // this line is important, if this content-type is not set it wont work
    body: 'foo=bar&blah=1'
});

构建body字符串的另一种方法是使用库,而不是像上面那样将其输入。例如query-string或qs包中的stringify函数。所以使用它看起来像这样:

import queryString from 'query-string'; // import the queryString class

fetch('url here', {
    method: 'POST',
    headers: {'Content-Type':'application/x-www-form-urlencoded'}, // this line is important, if this content-type is not set it wont work
    body: queryString.stringify({for:'bar', blah:1}) //use the stringify object of the queryString class
});

我认为你的问题是jsfiddle只能处理表单url编码的请求。但是让json请求的正确方法是将正确的json作为body传递:

fetch (https://httpbin.org/post, { 方法:“文章”, 标题:{ 'Accept': 'application/json, text/plain, */*', “内容类型”:“application / json” }, 身体:JSON。stringify({a: 7, str: 'Some string: &=&'}) })。然后res => res.json()) .then(res => console.log(res));

**//POST a request**


const createTodo = async (todo) =>  {
    let options = {
        method: "POST",
        headers: {
            "Content-Type":"application/json",
        },
        body: JSON.stringify(todo)      
    }
    let p = await fetch("https://jsonplaceholder.typicode.com/posts", options);
    let response = await p.json();
    return response;
}

**//GET request**

const getTodo = async (id) => {
    let response = await fetch('https://jsonplaceholder.typicode.com/posts/' + id);
  let r = await response.json();
  return r;
}
const mainFunc = async () => {
    let todo = {
            title: "milan7",
            body: "dai7",
            userID: 101
        }
    let todor = await createTodo(todo);
    console.log(todor);
    console.log(await getTodo(5));
}
mainFunc()

你可以用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));

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

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 => {
   ...
})