如何在 `gatsby js` 项目中处理文件上传?
How to handle file uploads in a `gatsby js` project?
在 netlify
上托管的 Gatsby Js
项目中有一个很好的 article 解释了如何处理表单提交。然而,它只是关于文本值提交,表单包含一些文件输入怎么样?
任何人都可以在这里阐明一些问题吗?
Netlify 无需任何特殊配置即可在其表单处理程序中支持文件上传:https://www.netlify.com/docs/form-handling/#file-uploads
Netlify Forms can receive files uploaded via form submissions. To do this, add an input with type="file"
to any form. When a form is submitted, a link to each uploaded file will be included in the form submission details. These are viewable in the Netlify app, in email notifications, and via our API.
感谢@coreyward 的帮助。我发现这里的问题是如何使用 javascript fetch API
到 post 表单数据。所以这里的解决方案非常简单:
const encode = (data) => {
const formData = new FormData()
Object.keys(data)
.map(key => {
if (key === 'files') {
for (const file of data[key]) {
formData.append(key, file, file.name)
}
} else {
formData.append(key, data[key])
}
})
return formData
}
await window.fetch('/', {
method: 'POST',
body: encode({ 'form-name': 'loan', ...this.state, userId: netlifyIdentity.currentUser().id }),
})
您会注意到,唯一棘手的部分是将 official sample article 的 encode
函数从 uri encoding
重写为 form data encoding
。
作为替代解决方案,您可以使用 Getform.io 在 Gatsby.js 项目中设置文件上传表单。
在此article中,他们展示了一个使用 Axios 的示例:
import axios from 'axios';
import React, { useState } from "react"
import 'bootstrap/dist/css/bootstrap.min.css';
const GETFORM_FORM_ENDPOINT = "YOUR-FORM-ENDPOINT";
function Form() {
const [formStatus, setFormStatus] = useState(false);
const [query, setQuery] = useState({
name: "",
email: "",
});
const handleFileChange = () => (e) => {
setQuery((prevState) => ({
...prevState,
files: e.target.files[0]
}));
};
const handleChange = () => (e) => {
const name = e.target.name;
const value = e.target.value;
setQuery((prevState) => ({
...prevState,
[name]: value
}));
};
const handleSubmit = (e) => {
e.preventDefault();
const formData = new FormData();
Object.entries(query).forEach(([key, value]) => {
formData.append(key, value);
});
axios
.post(
GETFORM_FORM_ENDPOINT,
formData,
{headers: {Accept: "application/json"}}
)
.then(function (response) {
setFormStatus(true);
setQuery({
name: "",
email: "",
});
console.log(response);
})
.catch(function (error) {
console.log(error);
});
};
return (
<div class="container-md">
<h2>Gatsby File Upload Form using Getform.io</h2>
<form
acceptCharset="UTF-8"
method="POST"
enctype="multipart/form-data"
id="gatsbyForm"
onSubmit={handleSubmit}
>
<div className="form-group mb-2">
<label for="exampleInputEmail1">Email address</label>
<input
type="email"
className="form-control"
placeholder="Enter your email"
required
name="email"
value={query.email}
onChange={handleChange()}
/>
</div>
<div className="form-group mb-2">
<label for="exampleInputName">Name</label>
<input
type="text"
className="form-control"
placeholder="Enter your name"
required
name="name"
value={query.name}
onChange={handleChange()}
/>
</div>
<hr/>
<div className="form-group mt-3">
<label className="mr-2">Upload your Resume:</label>
<input name="file" type="file" onChange={handleFileChange()}/>
</div>
<hr/>
{formStatus ? (
<div className="text-success mb-2">
Your message has been sent.
</div>
) : (
""
)}
<button type="submit" className="btn btn-primary">Submit</button>
</form>
</div>
);
}
export default Form
PS:在他们的免费计划中,他们允许您提交最大 5MB 的单个文件。
在 netlify
上托管的 Gatsby Js
项目中有一个很好的 article 解释了如何处理表单提交。然而,它只是关于文本值提交,表单包含一些文件输入怎么样?
任何人都可以在这里阐明一些问题吗?
Netlify 无需任何特殊配置即可在其表单处理程序中支持文件上传:https://www.netlify.com/docs/form-handling/#file-uploads
Netlify Forms can receive files uploaded via form submissions. To do this, add an input with
type="file"
to any form. When a form is submitted, a link to each uploaded file will be included in the form submission details. These are viewable in the Netlify app, in email notifications, and via our API.
感谢@coreyward 的帮助。我发现这里的问题是如何使用 javascript fetch API
到 post 表单数据。所以这里的解决方案非常简单:
const encode = (data) => {
const formData = new FormData()
Object.keys(data)
.map(key => {
if (key === 'files') {
for (const file of data[key]) {
formData.append(key, file, file.name)
}
} else {
formData.append(key, data[key])
}
})
return formData
}
await window.fetch('/', {
method: 'POST',
body: encode({ 'form-name': 'loan', ...this.state, userId: netlifyIdentity.currentUser().id }),
})
您会注意到,唯一棘手的部分是将 official sample article 的 encode
函数从 uri encoding
重写为 form data encoding
。
作为替代解决方案,您可以使用 Getform.io 在 Gatsby.js 项目中设置文件上传表单。
在此article中,他们展示了一个使用 Axios 的示例:
import axios from 'axios';
import React, { useState } from "react"
import 'bootstrap/dist/css/bootstrap.min.css';
const GETFORM_FORM_ENDPOINT = "YOUR-FORM-ENDPOINT";
function Form() {
const [formStatus, setFormStatus] = useState(false);
const [query, setQuery] = useState({
name: "",
email: "",
});
const handleFileChange = () => (e) => {
setQuery((prevState) => ({
...prevState,
files: e.target.files[0]
}));
};
const handleChange = () => (e) => {
const name = e.target.name;
const value = e.target.value;
setQuery((prevState) => ({
...prevState,
[name]: value
}));
};
const handleSubmit = (e) => {
e.preventDefault();
const formData = new FormData();
Object.entries(query).forEach(([key, value]) => {
formData.append(key, value);
});
axios
.post(
GETFORM_FORM_ENDPOINT,
formData,
{headers: {Accept: "application/json"}}
)
.then(function (response) {
setFormStatus(true);
setQuery({
name: "",
email: "",
});
console.log(response);
})
.catch(function (error) {
console.log(error);
});
};
return (
<div class="container-md">
<h2>Gatsby File Upload Form using Getform.io</h2>
<form
acceptCharset="UTF-8"
method="POST"
enctype="multipart/form-data"
id="gatsbyForm"
onSubmit={handleSubmit}
>
<div className="form-group mb-2">
<label for="exampleInputEmail1">Email address</label>
<input
type="email"
className="form-control"
placeholder="Enter your email"
required
name="email"
value={query.email}
onChange={handleChange()}
/>
</div>
<div className="form-group mb-2">
<label for="exampleInputName">Name</label>
<input
type="text"
className="form-control"
placeholder="Enter your name"
required
name="name"
value={query.name}
onChange={handleChange()}
/>
</div>
<hr/>
<div className="form-group mt-3">
<label className="mr-2">Upload your Resume:</label>
<input name="file" type="file" onChange={handleFileChange()}/>
</div>
<hr/>
{formStatus ? (
<div className="text-success mb-2">
Your message has been sent.
</div>
) : (
""
)}
<button type="submit" className="btn btn-primary">Submit</button>
</form>
</div>
);
}
export default Form
PS:在他们的免费计划中,他们允许您提交最大 5MB 的单个文件。