获取 API 上传文件时,JS 中的 preventDefault 不起作用

Posted

技术标签:

【中文标题】获取 API 上传文件时,JS 中的 preventDefault 不起作用【英文标题】:preventDefault in JS not working when fetch API upload files 【发布时间】:2021-09-23 13:09:46 【问题描述】:

我一直在尝试创建一个简单的网络应用程序,您可以在其中发布图像和一些描述。它适用于 Instagram 克隆项目。我在后端使用 multer 和 express 来解析正文和文件,它工作得很好。问题出在前端。我提供了一个表单,您可以在其中输入名称、描述和要上传的图像,然后使用 Fetch API 将正文发送到后端的我的 api。

我注意到每次提交表单时页面都会重新加载,尽管表单 sumbit 事件使用了 event.preventDefault() 和 event.stopPropagation()。

另外,我已经意识到它只有在上传文件时才会这样做,事实上,如果我单独留下名称和描述,它不会重新加载页面,而如果我在那里上传文件只是重新加载它。

这是 fetch API 的错误还是我没有考虑?

这是处理对我的 api 的获取请求的前端代码:

const instaForm = document.getElementById("post-pic");

instaForm.addEventListener("submit", (event) => 
  event.preventDefault();
  event.stopPropagation();
  let instaFormData = new FormData(instaForm);

  let url = `$baseUrl/create-insta`;

  fetch(url, 
    method: "POST",
    body: instaFormData,
  )
    .then((data) => data.json())
    .then((response) => 
      instaForm.reset();
      console.log(response);
    )
    .catch((err) => console.error(err));
);

考虑一下,如果我将文件的输入留空,页面不会重新加载,所以这肯定是文件上传的问题。

目前,为了调试我的 API,只发回一个简单的“已接收”响应,仅此而已。

html 表单

<form method="POST" id="post-pic" enctype="multipart/form-data">
        <input
          type="text"
          id="name"
          name="name"
          placeholder="Enter a name..."
        />
        <textarea
          name="description"
          id="description"
          rows="10"
          placeholder="A short description..."
        ></textarea>
        <input type="file" id="picture" name="insta" />
        <button id="publish" type="submit">Publish</button>
      </form>

【问题讨论】:

HTML 是什么样的?如果您对字段进行了 HTML5 验证(例如 required 属性),则不会触发 submit 事件。 HTML 中不需要任何字段。我通常用javascript来做。 Edit 您的问题,HTML 格式为代码。 检查控制台是否有错误 【参考方案1】:

您应该在单击表单按钮时捕捉到该事件。

试试这个:

<form method="POST" id="post-pic" enctype="multipart/form-data">
    <input
      type="text"
      id="name"
      name="name"
      placeholder="Enter a name..."
    />
    <textarea
      name="description"
      id="description"
      rows="10"
      placeholder="A short description..."
    ></textarea>
    <input type="file" id="picture" name="insta" />
    <button id="publish" type="button">Publish</button>
  </form>

JS 脚本:

const instaForm = document.getElementById("post-pic");

const buttonForm = document.getElementById("publish");

buttonForm.addEventListener("click",(event) => 

  event.preventDefault();

  let instaFormData = new FormData(instaForm);

  let url = `$baseUrl/create-insta`;
  
  fetch(url, 
  method: "POST",
  body: instaFormData,
  )
  .then((data) => data.json())
  .then((response) => 
   instaForm.reset();
   console.log(response);
   )
  .catch((err) => console.error(err));
   );


希望对你有帮助。 问候。

【讨论】:

实际上,它确实有效。这是一个聪明的解决方法。我现在更改了我的代码,因为我真的找不到答案。但是,我仍然很困惑这是一个 fetch API 错误、HTML 错误还是其他什么。谢谢。 很高兴能对 @BeGeos 有所帮助,您可以对代码进行一些改进,使其更具可读性,从 Promise (.then().then().catch() 到 asyn/await(异步函数) () => await fetch response ). 有链接可以看:Convert A Promise To ASYNC/AWAIT - Dev.to.

以上是关于获取 API 上传文件时,JS 中的 preventDefault 不起作用的主要内容,如果未能解决你的问题,请参考以下文章

在Laravel中通过AngularJs上传文件时获取值为null

怎么用js来获取 fileupload中的上传文件的文件名

怎么用js来获取 fileupload中的上传文件的文件名

使用 nextjs 应用程序中的 axios 将文件上传到 graphql api 服务器时我错在哪里?

如何在节点js中使用单个api保存文本字段值以及文件上传?

Html5 js FileReader接口(艺博会,添加商品时,上传图片,addGoods.html页)