Java基础、中级、高级、架构面试资料

如何使用Fetch API提交表单数据,fetch post JSON与formdata、文件上传实践

HTML5 herman 14浏览
公告:“业余草”微信公众号提供免费CSDN下载服务(只下Java资源),关注业余草微信公众号,添加作者微信:xttblog2,发送下载链接帮助你免费下载!
本博客日IP超过2000,PV 3000 左右,急需赞助商。
极客时间所有课程通过我的二维码购买后返现24元微信红包,请加博主新的微信号:xttblog2,之前的微信号好友位已满,备注:返现
受密码保护的文章请关注“业余草”公众号,回复关键字“0”获得密码
所有面试题(java、前端、数据库、springboot等)一网打尽,请关注文末小程序
视频教程免费领
腾讯云】1核2G5M轻量应用服务器50元首年,高性价比,助您轻松上云

最近,微信群里有网友讨论到,他使用 fetch api 接口,请求后台,使用 form表单的形式提交数据,总是失败。于是,向大家求教。

大家都知道,微信群有一个依赖,就是有事没事 @ 群主。群主真的是不堪其扰,这让我想起了,群智不是智,只是趋同。微信群里本来是互相交流,搞成了只向群主交流。

这个问题,我拿关键词,网上一搜,找出了一篇文章,描述的很详细:https://stackoverflow.com/questions/46640024/how-do-i-post-form-data-with-fetch-api。推荐大家看看。

下面,我们一起来学学。使用 Fetch API 提交表单数据的完整指南。

在现代 Web 开发中,Fetch API 已经成为与服务器交互的标准方式之一。相比传统的 XMLHttpRequest,Fetch API 提供了更简洁、更强大的功能。本文将详细介绍如何使用 Fetch API 提交表单数据,包括常规表单提交、文件上传以及处理各种响应类型。

为什么选择Fetch API提交表单数据

传统的表单提交会导致页面刷新,而使用Fetch API可以实现无刷新提交,提供更流畅的用户体验。Fetch API基于Promise设计,使得异步代码更易于编写和维护。

与jQuery的Ajax相比,Fetch API是原生JavaScript实现,不需要额外加载库,减少了页面负担。此外,Fetch API支持更现代的HTTP功能,如流式处理和请求/响应拦截。

基本表单数据提交

最简单的表单提交可以使用FormData对象收集表单数据:

const form = document.querySelector('form');

form.addEventListener('submit', (e) => {
  e.preventDefault();

  const formData = new FormData(form);

  fetch('/submit', {
    method: 'POST',
    body: formData
  })
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(error => console.error('Error:', error));
});

这段代码做了以下几件事:

  1. 阻止表单默认提交行为
  2. 创建FormData对象自动收集表单所有字段
  3. 使用Fetch API发送POST请求
  4. 处理JSON格式的响应

处理不同类型的表单数据

1. JSON数据提交

当后端期望接收JSON格式数据时:

fetch('/api/submit', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    username: 'example',
    password: 'securepassword'
  })
})

2. 文件上传

FormData天然支持文件上传,只需确保表单有enctype="multipart/form-data"属性:

<form id="uploadForm" enctype="multipart/form-data">
  <input type="file" name="fileUpload">
  <button type="submit">Upload</button>
</form>

JavaScript代码与基本表单提交相同,Fetch API会自动处理文件数据。

3. URL编码表单数据

对于传统的 application/x-www-form-urlencoded 格式:

const urlEncodedData = new URLSearchParams();
urlEncodedData.append('username', 'user1');
urlEncodedData.append('password', 'pass123');

fetch('/login', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded',
  },
  body: urlEncodedData
});

高级用法与最佳实践

1. 处理不同响应类型

Fetch API可以处理多种响应格式:

// 处理JSON响应
fetch('/api/data')
  .then(response => response.json())
  .then(data => console.log(data));

// 处理文本响应
fetch('/api/text')
  .then(response => response.text())
  .then(text => console.log(text));

// 处理Blob数据(如图片)
fetch('/image.png')
  .then(response => response.blob())
  .then(imageBlob => {
    const objectURL = URL.createObjectURL(imageBlob);
    document.getElementById('image').src = objectURL;
  });

2. 错误处理

Fetch API只有在网络错误时才会reject Promise,HTTP错误状态(如404, 500)仍会resolve。因此需要额外检查:

fetch('/api/data')
  .then(response => {
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }
    return response.json();
  })
  .catch(error => console.error('Error:', error));

3. 超时控制

Fetch API本身不支持超时设置,但可以通过Promise.race实现:

const timeout = (ms) => new Promise((_, reject) => 
  setTimeout(() => reject(new Error('Request timeout')), ms)
);

Promise.race([
  fetch('/api/data'),
  timeout(5000) // 5秒超时
])
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));

实际应用示例

用户注册表单

<form id="registerForm">
  <input type="text" name="username" placeholder="Username" required>
  <input type="email" name="email" placeholder="Email" required>
  <input type="password" name="password" placeholder="Password" required>
  <button type="submit">Register</button>
</form>

<div id="message"></div>
document.getElementById('registerForm').addEventListener('submit', async (e) => {
  e.preventDefault();

  const form = e.target;
  const messageDiv = document.getElementById('message');

  try {
    const response = await fetch('/api/register', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        username: form.username.value,
        email: form.email.value,
        password: form.password.value
      })
    });

    if (!response.ok) {
      const errorData = await response.json();
      throw new Error(errorData.message || 'Registration failed');
    }

    const data = await response.json();
    messageDiv.textContent = 'Registration successful!';
    messageDiv.style.color = 'green';

    // 可选:重定向或重置表单
    form.reset();

  } catch (error) {
    messageDiv.textContent = error.message;
    messageDiv.style.color = 'red';
  }
});

常见问题与解决方案

  1. CORS问题:确保服务器设置了正确的CORS头,或使用代理服务器
  2. CSRF保护:如果使用CSRF令牌,需要从表单或cookie中获取并添加到请求头:
const csrfToken = document.querySelector('meta[name="csrf-token"]').getAttribute('content');

fetch('/api/data', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-CSRF-TOKEN': csrfToken
  },
  body: JSON.stringify(data)
});
  1. 认证与授权:对于需要认证的请求,添加Authorization头:
fetch('/api/protected', {
  headers: {
    'Authorization': `Bearer ${localStorage.getItem('token')}`
  }
});

性能优化建议

  1. 请求取消:使用AbortController取消正在进行的请求:
const controller = new AbortController();

fetch('/api/data', {
  signal: controller.signal
})
.catch(err => {
  if (err.name === 'AbortError') {
    console.log('Fetch aborted');
  } else {
    console.error('Error:', err);
  }
});

// 取消请求
controller.abort();
  1. 数据压缩:确保服务器启用了gzip或Brotli压缩
  2. 批量请求:对于多个相关请求,考虑合并为一个请求

浏览器兼容性考虑

虽然大多数现代浏览器都支持Fetch API,但在旧版浏览器中可能需要polyfill:

<script src="https://cdn.jsdelivr.net/npm/whatwg-fetch@3.6.2/dist/fetch.umd.min.js"></script>

或者使用特性检测:

if (!window.fetch) {
  // 使用polyfill或回退方案
}

总结

Fetch API为表单提交提供了现代化、灵活的解决方案。通过本文介绍的技术,您可以:

  • 实现无刷新表单提交
  • 处理各种数据类型(JSON、FormData、文件等)
  • 实现健壮的错误处理和超时控制
  • 处理认证和授权需求
  • 优化请求性能

随着Web标准的不断发展,Fetch API已经成为前端开发中不可或缺的工具,掌握它的使用将极大提升您的Web开发效率。以上,希望能够帮助到更多的网友!

业余草公众号

最后,欢迎关注我的个人微信公众号:业余草(yyucao)!可加作者微信号:xttblog2。备注:“1”,添加博主微信拉你进微信群。备注错误不会同意好友申请。再次感谢您的关注!后续有精彩内容会第一时间发给您!原创文章投稿请发送至532009913@qq.com邮箱。商务合作也可添加作者微信进行联系!

本文原文出处:业余草: » 如何使用Fetch API提交表单数据,fetch post JSON与formdata、文件上传实践