请求失败,状态代码为 500 错误。在 React 中制作 multiForm 数据的表单 post 时
Request failed with status code 500 error. When making form post of multiForm data in React
我在发送表单的文件/照片元素时遇到问题。当 POST 到达后端时,它看起来像是 posting OK 但是当我单击提交时表单屏幕没有做任何事情并且 Web 开发控制台标记“请求失败,状态代码为 500 " 错误。
如果我的后端 API 工作正常,这可能是 CORS 错误吗?路由的文件路径在我的后端路由文件夹中与我的表单组件上的 axios post 请求相同。此外,我的 IDE 终端正在标记来自 posting 的正确文本正在访问后端(我知道我需要修复用户 ID,但我可以自己完成)。该文件也进入了它要进入的文件夹,但没有进入我的 Postgres/pgAdmin 数据库。
// state for the current field value
const [article, setArticle] = useState({
articleTitle: ``,
articleTypeID: ``,
articleContent: ``,
// photos: undefined,
userID: ``,
error: ``,
});
const [photos, setPhotos] = useState({
photos: null
})
const handleChange = (property) => (e) => {
setArticle({
// override the changed property and keep the rest
...article,
[property]: e.target.value,
});
}
const handleChangeInt = (property) => (e) => {
setArticle({
// override the changed property and keep the rest
...article,
[property]: parseInt(e.target.value),
});
}
const handleChangeFile = (photos) => (e) => {
this.setState({
selectedFiles: e.target.photos,
})
}
// get access to dispatch
const dispatch = useDispatch();
// useEffect with an empty dependency array is the same as componentDidMount
useEffect(() => {
dispatch(requireFieldData());
}, []);
function handleSubmitArticle(e: React.FormEvent<HTMLFormElement>) {
e.preventDefault();
const formData = new FormData();
formData.append("articleTitle", article.articleTitle);
formData.append("articleContent", article.articleContent);
formData.append("userID", article.userID);
formData.append("articleTypeID", article.articleTypeID);
formData.append("photos", photos);
axios.post("http://localhost:5002/api/article/createarticle", formData);
}
const classes = useStyles;
return (
<div>
<AppBar title="Enter your dive details"></AppBar>
<form
class="mt-4"
id="articleForm"
method="POST"
enctype="multipart/form-data"
onSubmit={handleSubmitArticle}>
<>
<Grid container spacing={3}
direction="row"
justify="center"
alignItems="center">
<Grid item xs={10}>
<TextField
placeholder="Article-Title"
label="Article Title"
name="articleTitle"
margin="normal"
value={article.articleTitle}
onChange={handleChange("articleTitle")}
fullWidth/>
</Grid>
<Grid item xs={5}>
<FormControl className={classes.formControl}>
<TextField
placeholder="Author-User-Number"
label="AuthorUserNumber"
// defaultValue={props.user.userID}
margin="normal"
value={props.user.userID}
onChange={handleChangeInt("userID")}
fullWidth/>
</FormControl>
</Grid>
<Grid item xs={5}>
<FormControl className={classes.formControl}>
<PopulateDropdown
dataList={articleTypeList}
titleProperty={"articleType"}
valueProperty={"articleTypeID"}
label="Article Type"
placeholder="Select article type"
value={article.articleTypeID}
onChange={handleChangeInt("articleTypeID")}/>
</FormControl>
</Grid>
<Grid item xs={10}>
<FormControl fullWidth className={classes.formControl}>
<TextField
placeholder="Article Content"
label="ArticleContent"
name="articleContent"
value={article.articleContent}
onChange={handleChange("articleContent")}
multiline
rowsMax={6}
fullWidth/>
</FormControl>
</Grid>
<br />
<Grid item xs={10}>
<div class="form-control">
<label for="photos">Photo Upload</label>
<input
type="file"
name="photos"
id="photos"
// value={article.photos}
onChange={(e) => {
setPhotos(e.target.files?.[0]);
}}
/>
</div>
</Grid>
<br />
<Grid item xs={8} md={6}>
<Button variant="primary" type="submit">
Submit</Button>
</Grid>
</Grid>
</>
</form>
更新
这可能与我的后端路由处理 formData 的方式有关吗?报错信息好像是axios错误。
// create article
app.post('/api/article/createarticle', upload.single("photos"), controller.createArticle);
更新
我已经将 Multer 添加到后端的路由中。除了上传部分,我还需要做任何其他事情吗?后端 API 完美运行,所以我认为这与后端无关。 Postman 表单数据 API 有效,所以我认为它可以正常处理表单数据。
const multer = require('multer');
const upload = multer({ dest: './assets/article/' })
module.exports = function(app) {
app.post('/api/article/createarticle', upload.single("photos"), controller.createArticle);
后端似乎需要 Multer 之类的东西
问题:
从这条错误消息中可以看出,您的请求正文被解析为 JSON
:
.
但是您发送的是 FormData
,类型为 multipart/form-data
。
Express自带body-parser
,无法处理multipart bodys:
This does not handle multipart bodies, due to their complex and typically large nature. For multipart bodies, you may be interested in the following modules:
- busboy and connect-busboy
- multiparty and connect-multiparty
- formidable
- multer
解决方案:
发送JSON数据。你真的不需要表单数据,除非你有复杂的东西,比如文件输入
axios.post("http://localhost:5002/api/article/createarticle", article)
//== Plain JS object which will be converted to JSON string ========^
使用上面提到的可以处理表单数据的中间件。例如穆勒:
var express = require('express')
var app = express()
var multer = require('multer')
var upload = multer()
app.post('/createarticle', upload.none(), function (req, res, next) {
// req.body contains the text fields
})
我已经找到问题的原因。我的表单数据需要一些配置逻辑来处理如下表单数据。
function handleSubmitArticle(e: React.FormEvent<HTMLFormElement>) {
e.preventDefault();
const formData = new FormData();
formData.append("articleTitle", article.articleTitle);
formData.append("articleContent", article.articleContent);
formData.append("userID", article.userID);
formData.append("articleTypeID", article.articleTypeID);
formData.append("photos", photos);
const config = {
headers: {
'content-type': 'multipart/form-data'
}
};
axios.post("http://localhost:5002/api/article/createarticle", formData, config);
}
我还需要添加一个方法来处理文件到我的照片输入的 onChange 部分。
<label for="photos">Photo Upload</label>
<input
type="file"
name="photos"
id="photos"
// value={article.photos}
onChange={(e) => {
console.log(e.target.files)
if (e.target.files && e.target.files[0]) {
let img = e.target.files[0];
setPhotos(img)
}
// setPhotos(e.target.photos.[0]);
}}
/>
我在发送表单的文件/照片元素时遇到问题。当 POST 到达后端时,它看起来像是 posting OK 但是当我单击提交时表单屏幕没有做任何事情并且 Web 开发控制台标记“请求失败,状态代码为 500 " 错误。
如果我的后端 API 工作正常,这可能是 CORS 错误吗?路由的文件路径在我的后端路由文件夹中与我的表单组件上的 axios post 请求相同。此外,我的 IDE 终端正在标记来自 posting 的正确文本正在访问后端(我知道我需要修复用户 ID,但我可以自己完成)。该文件也进入了它要进入的文件夹,但没有进入我的 Postgres/pgAdmin 数据库。
// state for the current field value
const [article, setArticle] = useState({
articleTitle: ``,
articleTypeID: ``,
articleContent: ``,
// photos: undefined,
userID: ``,
error: ``,
});
const [photos, setPhotos] = useState({
photos: null
})
const handleChange = (property) => (e) => {
setArticle({
// override the changed property and keep the rest
...article,
[property]: e.target.value,
});
}
const handleChangeInt = (property) => (e) => {
setArticle({
// override the changed property and keep the rest
...article,
[property]: parseInt(e.target.value),
});
}
const handleChangeFile = (photos) => (e) => {
this.setState({
selectedFiles: e.target.photos,
})
}
// get access to dispatch
const dispatch = useDispatch();
// useEffect with an empty dependency array is the same as componentDidMount
useEffect(() => {
dispatch(requireFieldData());
}, []);
function handleSubmitArticle(e: React.FormEvent<HTMLFormElement>) {
e.preventDefault();
const formData = new FormData();
formData.append("articleTitle", article.articleTitle);
formData.append("articleContent", article.articleContent);
formData.append("userID", article.userID);
formData.append("articleTypeID", article.articleTypeID);
formData.append("photos", photos);
axios.post("http://localhost:5002/api/article/createarticle", formData);
}
const classes = useStyles;
return (
<div>
<AppBar title="Enter your dive details"></AppBar>
<form
class="mt-4"
id="articleForm"
method="POST"
enctype="multipart/form-data"
onSubmit={handleSubmitArticle}>
<>
<Grid container spacing={3}
direction="row"
justify="center"
alignItems="center">
<Grid item xs={10}>
<TextField
placeholder="Article-Title"
label="Article Title"
name="articleTitle"
margin="normal"
value={article.articleTitle}
onChange={handleChange("articleTitle")}
fullWidth/>
</Grid>
<Grid item xs={5}>
<FormControl className={classes.formControl}>
<TextField
placeholder="Author-User-Number"
label="AuthorUserNumber"
// defaultValue={props.user.userID}
margin="normal"
value={props.user.userID}
onChange={handleChangeInt("userID")}
fullWidth/>
</FormControl>
</Grid>
<Grid item xs={5}>
<FormControl className={classes.formControl}>
<PopulateDropdown
dataList={articleTypeList}
titleProperty={"articleType"}
valueProperty={"articleTypeID"}
label="Article Type"
placeholder="Select article type"
value={article.articleTypeID}
onChange={handleChangeInt("articleTypeID")}/>
</FormControl>
</Grid>
<Grid item xs={10}>
<FormControl fullWidth className={classes.formControl}>
<TextField
placeholder="Article Content"
label="ArticleContent"
name="articleContent"
value={article.articleContent}
onChange={handleChange("articleContent")}
multiline
rowsMax={6}
fullWidth/>
</FormControl>
</Grid>
<br />
<Grid item xs={10}>
<div class="form-control">
<label for="photos">Photo Upload</label>
<input
type="file"
name="photos"
id="photos"
// value={article.photos}
onChange={(e) => {
setPhotos(e.target.files?.[0]);
}}
/>
</div>
</Grid>
<br />
<Grid item xs={8} md={6}>
<Button variant="primary" type="submit">
Submit</Button>
</Grid>
</Grid>
</>
</form>
更新
这可能与我的后端路由处理 formData 的方式有关吗?报错信息好像是axios错误。
// create article
app.post('/api/article/createarticle', upload.single("photos"), controller.createArticle);
更新
我已经将 Multer 添加到后端的路由中。除了上传部分,我还需要做任何其他事情吗?后端 API 完美运行,所以我认为这与后端无关。 Postman 表单数据 API 有效,所以我认为它可以正常处理表单数据。
const multer = require('multer');
const upload = multer({ dest: './assets/article/' })
module.exports = function(app) {
app.post('/api/article/createarticle', upload.single("photos"), controller.createArticle);
后端似乎需要 Multer 之类的东西
问题:
从这条错误消息中可以看出,您的请求正文被解析为 JSON
:
但是您发送的是 FormData
,类型为 multipart/form-data
。
Express自带body-parser
,无法处理multipart bodys:
This does not handle multipart bodies, due to their complex and typically large nature. For multipart bodies, you may be interested in the following modules:
- busboy and connect-busboy
- multiparty and connect-multiparty
- formidable
- multer
解决方案:
发送JSON数据。你真的不需要表单数据,除非你有复杂的东西,比如文件输入
axios.post("http://localhost:5002/api/article/createarticle", article) //== Plain JS object which will be converted to JSON string ========^
使用上面提到的可以处理表单数据的中间件。例如穆勒:
var express = require('express') var app = express() var multer = require('multer') var upload = multer() app.post('/createarticle', upload.none(), function (req, res, next) { // req.body contains the text fields })
我已经找到问题的原因。我的表单数据需要一些配置逻辑来处理如下表单数据。
function handleSubmitArticle(e: React.FormEvent<HTMLFormElement>) {
e.preventDefault();
const formData = new FormData();
formData.append("articleTitle", article.articleTitle);
formData.append("articleContent", article.articleContent);
formData.append("userID", article.userID);
formData.append("articleTypeID", article.articleTypeID);
formData.append("photos", photos);
const config = {
headers: {
'content-type': 'multipart/form-data'
}
};
axios.post("http://localhost:5002/api/article/createarticle", formData, config);
}
我还需要添加一个方法来处理文件到我的照片输入的 onChange 部分。
<label for="photos">Photo Upload</label>
<input
type="file"
name="photos"
id="photos"
// value={article.photos}
onChange={(e) => {
console.log(e.target.files)
if (e.target.files && e.target.files[0]) {
let img = e.target.files[0];
setPhotos(img)
}
// setPhotos(e.target.photos.[0]);
}}
/>