【问题标题】:POST Request with Fetch API?使用 Fetch API 发布请求?
【发布时间】:2017-01-26 16:51:48
【问题描述】:

我知道使用新的 Fetch API(此处与 ES2017 的 async/await 一起使用)您可以发出这样的 GET 请求:

async getData() {
    try {
        let response = await fetch('https://example.com/api');
        let responseJson = await response.json();
        console.log(responseJson);
    } catch(error) {
        console.error(error);
    }
}

但是如何发出 POST 请求呢?

【问题讨论】:

  • 你把两个不同的东西混为一谈:JavaScript 即将推出的async/await 和(完全独立的)Fetch API。你的问题与 JavaScript 的async/await 无关,是关于fetch。 (另请注意,新的 Fetch API 就是这样,新的,所以 support is limited to cutting-edge browsers。)
  • @jfriend00:我为他们做了。

标签: javascript fetch-api


【解决方案1】:

长话短说,Fetch 还允许您传递对象以获得更个性化的请求:

fetch("http://example.com/api/endpoint/", {
  method: "post",
  headers: {
    'Accept': 'application/json',
    'Content-Type': 'application/json'
  },

  //make sure to serialize your JSON body
  body: JSON.stringify({
    name: myName,
    password: myPassword
  })
})
.then( (response) => { 
   //do something awesome that makes the world a better place
});

查看 fetch 文档了解更多好东西和陷阱:

https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch

请注意,由于您使用的是异步 try/catch 模式,因此在我的示例中您将省略 then() 函数;)

【讨论】:

  • 为什么选择 JSON.stringify ?如何发送简单的表单数据?!
  • 这只是一个 POST 对象的例子。要从具有许多输入的表单中发布数据,我建议研究将表单数据序列化为字符串的方法。如果使用 jQuery,这可以使用 $.serialize() 方法来完成。如果使用纯 JS,请查看此线程:stackoverflow.com/questions/11661187/…
  • 总体虽然理想是一样的,但你可能会将表单数据转换为对象并使用JSON.serialize()进行序列化
  • 这对我有用,谢谢。我用 Axios 替换了 Fetch API,现在我所有的 POST 请求都成功了。很遗憾我不能正确使用 Axios。
【解决方案2】:

如果您想在不以 JSON 格式发送数据的情况下发出简单的发布请求。

fetch("/url-to-post",
{
    method: "POST",

    // whatever data you want to post with a key-value pair

    body: "name=manas&age=20",
    headers: 
    {
        "Content-Type": "application/x-www-form-urlencoded"
    }

}).then((response) => 
{ 
    // do something awesome that makes the world a better place
});

【讨论】:

  • 在更新 fetch 时发现了这个。无需对 php 输入流进行额外的后端处理即可完美地获取一般帖子。
【解决方案3】:

这是一个完整的例子:在花了几个小时修改不完整的代码 sn-ps 之后,我终于设法从 javascript 中发布了一些 json,在服务器上使用 php 获取它,添加了一个数据字段,最后更新了原始网页。这里是 HTML、PHP 和 JS。感谢所有发布这里收集的原始代码片段的人。类似的代码在这里上线:https://www.nbest.co.uk/Fetch/index.php

<!DOCTYPE HTML>
<!-- Save this to index.php and view this page in your browser -->
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Javascript Fetch Example</title>
</head>

<body>
<h1>Javascript Fetch Example</h1>
<p>Save this to index.php and view this page in your browser.</p>

<button type="button" onclick="myButtonClick()">Press Me</button>

<p id="before">This is the JSON before the fetch.</p>
<p id="after">This is the JSON after the fetch.</p>

<script src="fetch.js"></script>

</body>
</html>
<!-- --------------------------------------------------------- -->

// Save this as fetch.js --------------------------------------------------------------------------

function success(json) {
  document.getElementById('after').innerHTML = "AFTER: " + JSON.stringify(json);
  console.log("AFTER: " + JSON.stringify(json));
} // ----------------------------------------------------------------------------------------------

function failure(error) {
  document.getElementById('after').innerHTML = "ERROR: " + error;
  console.log("ERROR: " + error);
} // ----------------------------------------------------------------------------------------------

function myButtonClick() {
  var url    = 'json.php';
  var before = {foo: 'Hello World!'};

  document.getElementById('before').innerHTML = "BEFORE: " + JSON.stringify(before);
  console.log("BEFORE: " + JSON.stringify(before));

  fetch(url, {
    method: 'POST', 
    body: JSON.stringify(before),
    headers:{
      'Content-Type': 'application/json'
    }
  }).then(res => res.json())
  .then(response => success(response))
  .catch(error => failure(error));
} // ----------------------------------------------------------------------------------------------

<?php
  // Save this to json.php ---------------------------------------
  $contentType = isset($_SERVER["CONTENT_TYPE"]) ? trim($_SERVER["CONTENT_TYPE"]) : '';

  if ($contentType === "application/json") {
    $content = trim(file_get_contents("php://input"));

    $decoded = json_decode($content, true);

    $decoded['bar'] = "Hello World AGAIN!";    // Add some data to be returned.

    $reply = json_encode($decoded);
  }  

  header("Content-Type: application/json; charset=UTF-8");
  echo $reply;
  // -------------------------------------------------------------
?>

【讨论】:

    【解决方案4】:

    将表单数据发布到 PHP 脚本的最佳方式是 Fetch API。这是一个例子:

    function postData() {
      const form = document.getElementById('form')
      let data = new FormData()
      data.append('name', form.name.value)
    
      fetch('../php/contact.php', {
        method: 'POST',
        body: data,
      }).then(response => {
        if (!response.ok) {
          throw new Error('Network response was not ok.')
        }
      }).catch(console.error)
    }
    <form id="form" action="javascript:postData()">
      <input id="name" name="name" placeholder="Name" type="text" required>
      <input type="submit" value="Submit">
    </form>

    这是一个非常基本的 PHP 脚本示例,它获取数据并发送电子邮件:

    <?php
        header('Content-type: text/html; charset=utf-8');
    
        if (isset($_POST['name'])) {
            $name = $_POST['name'];
        }
    
        $to = "test@example.com";
        $subject = "New name submitted";
        $body = "You received the following name: $name";
        
        mail($to, $subject, $body);
    

    【讨论】:

    • 实际上,只有这适用于 PHP。序列化键值对象和键值查询字符串都不适用于 fetch。
    • 我认为 FormData 是发送数据的正确方式。它的工作方式与使用表单提交相同。
    【解决方案5】:

    这是一个使用 node-fetch 的 POST 请求的解决方案,带有 async/await。

    async function post(data) {
        try {
            // Create request to api service
            const req = await fetch('http://127.0.0.1/api', {
                method: 'POST',
                headers: { 'Content-Type':'application/json' },
                
                // format the data
                body: JSON.stringify({
                    id: data.id,
                    foo: data.foo,
                    bar: data.bar
                }),
            });
            
            const res = await req.json();
    
            // Log success message
            console.log(res);                
        } catch(err) {
            console.error(`ERROR: ${err}`);
        }
    }
    
    // Call your function
    post() // with your parameter of Course
    

    【讨论】:

      【解决方案6】:

      在这个article中,我描述了fetch()的第二个参数。

      用于提交 JSON 数据

      const user =  { name:  'Sabesan', surname:  'Sathananthan'  };
      const response = await fetch('/article/fetch/post/user', {
        method: 'POST',
        headers: {
         'Content-Type': 'application/json;charset=utf-8'
        }, 
        body: JSON.stringify(user) 
      });
      

      提交表单

      const form = document.querySelector('form');
      
      const response = await fetch('/users', {
        method: 'POST',
        body: new FormData(form)
      })
      

      用于文件上传

      const input = document.querySelector('input[type="file"]');
      
      const data = new FormData();
      data.append('file', input.files[0]);
      data.append('user', 'foo');
      
      fetch('/avatars', {
        method: 'POST',
        body: data
      });
      

      【讨论】:

        【解决方案7】:

        2021 年回答:以防万一您在这里寻找如何使用 async/await 或 Promise 发出 GET 和 POST Fetch api 请求(与 axios 相比)。

        我用jsonplaceholder fake API来演示:

        使用 async/await 获取 api GET 请求:

                 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()
        

        使用 async/await 获取 api POST 请求:

            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()
        

        使用 Promises 获取请求:

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

        使用 Promises 的 POST 请求:

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

        使用 Axios 获取请求:

                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()
        

        使用 Axios 的 POST 请求:

        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()
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2020-11-11
          • 1970-01-01
          • 2021-12-03
          • 2020-11-24
          • 2022-12-23
          相关资源
          最近更新 更多