使用Fetch API进行POST请求?

72

我知道使用新的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请求?


3
你把两件不同的事情混淆了:JavaScript 即将推出的 async/await 和 (完全独立的) Fetch API。你的问题与 JavaScript 的 async/await 没有任何关系,而是关于 fetch。另外请注意,新的 Fetch API 是新的,因此仅支持最先进的浏览器 - T.J. Crowder
@jfriend00:我已经为他们做到了。 - T.J. Crowder
7个回答

151

简而言之,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()函数 ;)


8
为什么要使用 JSON.stringify? 如何发送简单表单数据? - Vincent Decaux
1
这只是一个POST对象的示例。要从具有多个输入的表单中POST数据,我建议研究将表单数据序列化为字符串的方法。 如果使用jQuery,可以使用$.serialize()方法来完成此操作。如果使用普通JS,请查看此线程:https://dev59.com/6Wgu5IYBdhLWcg3wASWO - hellojebus
总的来说,虽然理想是相同的,但您可能会将表单数据转换为对象,并使用JSON.serialize()进行序列化。 - hellojebus
1
这对我很有帮助,谢谢。我用Fetch API替换了Axios,现在我的所有POST请求都成功了。很遗憾我不能正确使用Axios。 - Felipe Wagner
点赞这条评论:“做一些令世界变得更美好的了不起的事情” - Luffy D. Monkey

32

如果你想发送一个简单的 POST 请求而不是发送 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输入流进行额外的后端处理。 - spyke01

13

如何将表单数据POST到PHP脚本

最好的方法是利用Fetch APIFormData接口。以下是一个示例:

function postData() {
  const form = document.getElementById('form');
  const data = new FormData();
  data.append('name', form.name.value);

  try {
    const res = fetch('../php/contact.php', {
      method: 'POST',
      headers: {
        "content-type": "multipart/form-data"
      },
      body: data,
    });

    if (!res.ok) console.log(`POST failed with ${res.status}.`);
  } catch(err) {
    console.error(err);
  }
}
<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);

2
实际上,只有这个适用于PHP。序列化键值对象和键值查询字符串都不能与fetch一起使用。 - Michael Zelensky
1
我认为FormData是发送数据的正确方式。这将与使用表单提交相同。 - jcubic

9

2021年的答案:以防你在这里找如何使用async/await或promises与axios相比制作GET和POST Fetch api请求的方法。

我使用jsonplaceholder假API演示:

使用async/await进行Fetch 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进行Fetch 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 发送 GET 请求:

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

使用Promise进行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 使用 GET 请求:

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

4

以下是使用 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

1
在这篇文章中,我描述了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
});

1
下面是一个完整的例子:经过数小时的琢磨,我终于成功地使用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;
  // -------------------------------------------------------------
?>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接