Javascript 获取:发布JSON数据

Javascript 获取:发布JSON数据,javascript,json,fetch-api,Javascript,Json,Fetch Api,我正在尝试使用发布一个JSON对象 据我所知,我需要在请求正文中附加一个字符串化对象,例如: fetch(“/echo/json/”, { 标题:{ “接受”:“应用程序/json”, “内容类型”:“应用程序/json” }, 方法:“张贴”, 正文:JSON.stringify({a:1,b:2}) }) .then(函数(res){console.log(res)}) .catch(函数(res){console.log(res)}) 使用时,我希望看到我发送的对象({a:1,b:2})

我正在尝试使用发布一个JSON对象

据我所知,我需要在请求正文中附加一个字符串化对象,例如:

fetch(“/echo/json/”,
{
标题:{
“接受”:“应用程序/json”,
“内容类型”:“应用程序/json”
},
方法:“张贴”,
正文:JSON.stringify({a:1,b:2})
})
.then(函数(res){console.log(res)})
.catch(函数(res){console.log(res)})

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

花费一些时间后,反向工程JSFIDLE,试图生成有效负载-这是有效果的

请在
return 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:&&Firefox>39&&Chrome>42

使用ES2017,以下是如何发布JSON有效负载:

(异步()=>{
const rawResponse=等待提取('https://httpbin.org/post', {
方法:“POST”,
标题:{
“接受”:“应用程序/json”,
“内容类型”:“应用程序/json”
},
正文:JSON.stringify({a:1,b:'text content'})
});
const content=await rawResponse.json();
控制台日志(内容);

})();在搜索引擎中,我用fetch处理了非json发布数据的主题,所以我想添加这个

对于非json,您不必使用表单数据。您只需将
内容类型
标题设置为
应用程序/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'
});
构建
主体
字符串的另一种方法是使用库,而不是像我上面所做的那样键入它。例如,来自或包的
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
只能处理
表单urlencoded
请求

但发出json请求的正确方法是将正确的
json
作为一个主体传递:

fetch('https://httpbin.org/post', {
方法:“post”,
标题:{
“Accept':“application/json,text/plain,*/*”,
“内容类型”:“应用程序/json”
},
body:JSON.stringify({a:7,str:'Some string:&=&'})
}).then(res=>res.json())

.then(res=>console.log(res))如果您使用的是纯json REST API,我已经在fetch()周围创建了一个薄包装,并进行了许多改进:

//改进fetch()用法的小型库
const api=函数(方法、url、数据、头={}){
返回获取(url{
方法:method.toUpperCase(),
body:JSON.stringify(data),//将其作为stringized JSON发送
credentials:api.credentials,//用于在请求上保持会话
headers:Object.assign({},api.headers,headers)//扩展头
}).then(res=>res.ok?res.json():Promise.reject(res));
};
//可以全局覆盖的默认值
api.credentials='include';
api.headers={
“csrf令牌”:window.csrf | |“”,//仅当全局设置时,否则忽略
'Accept':'application/json',//接收json
'内容类型':'应用程序/json'//发送json
};
//方便的方法
['get','post','put','delete'].forEach(方法=>{
api[method]=api.bind(null,method);
});
要使用它,可以使用变量
api
和4种方法:

api.get('/todo')。然后(all=>{/*…*/});
异步
功能中:

const all=wait-api.get('/todo');
// ...
jQuery的示例:

$('.like')。在('click',async e=>{
const id=123;//获取它,但它更适合
wait api.put(`/like/${id}`,{like:true});
//无论如何:
$(e.target).addClass('active disfect').removeClass('like');
});

这与
内容类型相关。正如您可能从其他讨论和对这个问题的回答中注意到的,一些人通过设置
内容类型:“application/json”
就可以解决这个问题。不幸的是,在我的情况下,它没有工作,我的POST请求在服务器端仍然是空的

但是,如果您尝试使用jQuery的
$.post()
并且它工作正常,原因可能是jQuery使用
内容类型:“x-www-form-urlencoded”
而不是
应用程序/json

data = Object.keys(data).map(key => encodeURIComponent(key) + '=' + encodeURIComponent(data[key])).join('&')
fetch('/api/', {
    method: 'post', 
    credentials: "include", 
    body: data, 
    headers: {'Content-Type': 'application/x-www-form-urlencoded'}
})

有相同的问题-没有
正文
从客户端发送到服务器

添加
内容类型
标题为我解决了这个问题:

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

它可能对某人有用:

我有一个问题,formdata没有按照我的请求发送

在我的例子中,以下标题的组合也导致了问题和错误的内容类型

所以我在请求中发送了这两个头,当我删除有效的头时,它没有发送formdata

同样,其他答案表明内容类型标题需要正确

对于我的请求,正确的内容类型标题为:

“内容类型”:“application/x-www-form-urlencoded;charset=UTF-8”


所以底线是,如果您的formdata没有附加到请求,那么它可能是您的头。请尽量减少标题,然后尝试逐个添加标题,以查看问题是否得到解决。

我认为,我们不需要将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'
curl -v -X POST -H 'Content-type: application/x-www-form-urlencoded' -d '@data.txt' '/echo/form'
如果远程服务不接受json文件作为主体,只需发送数据表单:

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/json' -d '@data.json' '/echo/json'
curl -v -X POST -H 'Content-type: application/x-www-form-urlencoded' -d '@data.txt' '/echo/form'

上面的答案不适用于PHP7,因为它的编码错误,但我可以用其他答案找出正确的编码。此代码还发送身份验证cookie,在处理例如PHP论坛时,您可能需要这些cookie:

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);
    });
}

如果JSON负载包含数组和嵌套对象,我将使用
URLSearc
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'
    }
});
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);
});    
Object.defineProperties(FormData.prototype, { // extend FormData for direct use of js objects
    load: {
       value: function (d) {
                   for (var v in d) {
                      this.append(v, typeof d[v] === 'string' ? d[v] : JSON.stringify(d[v]));
                   }
               }
           }
   })

var F = new FormData;
F.load({A:1,B:2});

fetch('url_target?C=3&D=blabla', {
        method: "POST", 
          body: F
     }).then( response_handler )
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 };
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(_url, _options)
  .then((res) => res.json())
  .then((json) => console.log(json));
         const asyncGetCall = async () => {
            try {
                const response = await fetch('https://jsonplaceholder.typicode.com/posts');
                 const data = await response.json();
                // enter you logic when the fetch is successful
                 console.log(data);
               } catch(error) {
            // enter your logic for when there is an error (ex. error toast)
                  console.log(error)
                 } 
            }


          asyncGetCall()
    const asyncPostCall = async () => {
            try {
                const response = await fetch('https://jsonplaceholder.typicode.com/posts', {
                 method: 'POST',
                 headers: {
                   'Content-Type': 'application/json'
                   },
                   body: JSON.stringify({
             // your expected POST request payload goes here
                     title: "My post title",
                     body: "My post content."
                    })
                 });
                 const data = await response.json();
              // enter you logic when the fetch is successful
                 console.log(data);
               } catch(error) {
             // enter your logic for when there is an error (ex. error toast)

                  console.log(error)
                 } 
            }

asyncPostCall()
  fetch('https://jsonplaceholder.typicode.com/posts')
  .then(res => res.json())
  .then(data => {
   // enter you logic when the fetch is successful
    console.log(data)
  })
  .catch(error => {
    // enter your logic for when there is an error (ex. error toast)
   console.log(error)
  })
fetch('https://jsonplaceholder.typicode.com/posts', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
   body: JSON.stringify({
     // your expected POST request payload goes here
      title: "My post title",
      body: "My post content."
      })
})
  .then(res => res.json())
  .then(data => {
   // enter you logic when the fetch is successful
    console.log(data)
  })
  .catch(error => {
  // enter your logic for when there is an error (ex. error toast)
   console.log(error)
  })  
        const axiosGetCall = async () => {
            try {
              const { data } = await axios.get('https://jsonplaceholder.typicode.com/posts')
    // enter you logic when the fetch is successful
              console.log(`data: `, data)
           
            } catch (error) {
    // enter your logic for when there is an error (ex. error toast)
              console.log(`error: `, error)
            }
          }
    
    axiosGetCall()
const axiosPostCall = async () => {
    try {
      const { data } = await axios.post('https://jsonplaceholder.typicode.com/posts',  {
      // your expected POST request payload goes here
      title: "My post title",
      body: "My post content."
      })
   // enter you logic when the fetch is successful
      console.log(`data: `, data)
   
    } catch (error) {
  // enter your logic for when there is an error (ex. error toast)
      console.log(`error: `, error)
    }
  }


axiosPostCall()