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


当前回答

我认为,我们不需要将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'

其他回答

在花了一些时间后,反向工程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

如果你使用纯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');
});

我认为你的问题是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));

在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对象解析为字符串,如果远程服务器接受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'