获取 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