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


当前回答

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

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

其他回答

在花了一些时间后,反向工程jsFiddle,试图生成有效负载-有一个效果。

请采取眼睛(照顾)在线返回response.json();这里的回应不是回应,而是承诺。

var json = {
    json: JSON.stringify({
        a: 1,
        b: 2
    }),
    delay: 3
};

fetch('/echo/json/', {
    method: 'post',
    headers: {
        'Accept': 'application/json, text/plain, */*',
        'Content-Type': 'application/json'
    },
    body: 'json=' + encodeURIComponent(JSON.stringify(json.json)) + '&delay=' + json.delay
})
.then(function (response) {
    return response.json();
})
.then(function (result) {
    alert(result);
})
.catch (function (error) {
    console.log('Request failed', error);
});

jsFiddle: http://jsfiddle.net/egxt6cpz/46/ && Firefox > 39 && Chrome > 42

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

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

在ES2017 async/await支持下,如何POST一个JSON有效负载:

(async () => { const rawResponse =等待取回('https://httpbin.org/post', { 方法:“文章”, 标题:{ “接受”:application / json, “内容类型”:“application / json” }, 身体:JSON。stringify({a: 1, b: '文本内容'}) }); const content = await rawResponse.json(); console.log(内容); }) ();

不能使用ES2017?参见@vp_art使用承诺的回答

然而,这个问题是由一个长期以来固定的chrome错误引起的问题。 以下是原来的答案。

chrome devtools甚至不显示JSON作为请求的一部分

这是真正的问题,这是chrome开发工具的一个bug,在chrome 46中修复。

这段代码工作得很好-它正确地发布了JSON,只是不能被看到。

我希望看到我发回的对象

这是行不通的,因为这不是JSfiddle的正确格式。

正确的代码是:

var payload = {
    a: 1,
    b: 2
};

var data = new FormData();
data.append( "json", JSON.stringify( payload ) );

fetch("/echo/json/",
{
    method: "POST",
    body: data
})
.then(function(res){ return res.json(); })
.then(function(data){ alert( JSON.stringify( data ) ) })

对于接受JSON有效负载的端点,原始代码是正确的

如果你使用纯json REST API,我已经在fetch()周围创建了一个薄包装器,其中有许多改进:

// Small library to improve on fetch() usage
const api = function(method, url, data, headers = {}){
  return fetch(url, {
    method: method.toUpperCase(),
    body: JSON.stringify(data),  // send it as stringified json
    credentials: api.credentials,  // to keep the session on the request
    headers: Object.assign({}, api.headers, headers)  // extend the headers
  }).then(res => res.ok ? res.json() : Promise.reject(res));
};

// Defaults that can be globally overwritten
api.credentials = 'include';
api.headers = {
  'csrf-token': window.csrf || '',    // only if globally set, otherwise ignored
  'Accept': 'application/json',       // receive json
  'Content-Type': 'application/json'  // send json
};

// Convenient methods
['get', 'post', 'put', 'delete'].forEach(method => {
  api[method] = api.bind(null, method);
});

要使用它,你有变量api和4个方法:

api.get('/todo').then(all => { /* ... */ });

在一个async函数中:

const all = await api.get('/todo');
// ...

jQuery示例:

$('.like').on('click', async e => {
  const id = 123;  // Get it however it is better suited

  await api.put(`/like/${id}`, { like: true });

  // Whatever:
  $(e.target).addClass('active dislike').removeClass('like');
});

你只需要检查响应是否正常,因为调用没有返回任何东西。

var json = {
    json: JSON.stringify({
        a: 1,
        b: 2
    }),
    delay: 3
};

fetch('/echo/json/', {
    method: 'post',
    headers: {
        'Accept': 'application/json, text/plain, */*',
        'Content-Type': 'application/json'
    },
    body: 'json=' + encodeURIComponent(JSON.stringify(json.json)) + '&delay=' + json.delay
})
.then((response) => {if(response.ok){alert("the call works ok")}})
.catch (function (error) {
    console.log('Request failed', error);
});