node.js - 多部分表单组件 "cannot POST/divespotform"无法正常工作 parseInt 问题?

标签 node.js reactjs express redux multipartform-data

我有一个多部分表单,我即将完成工作,但仍未发布到我的后端数据库。这可能与我没有正确地将两个 ID 字段解析为整数有关吗?

这两个文本字段和文件字段看起来像是在请求中正确发送的。随机的粉色/蓝色/黑色/红色符号是否是图像发送到后端的?我的两个 ID int 字段是否也应该显示在此处,因为它们位于同一表单上?

我的参数 1 的方法不是一个对象似乎与我的句柄提交方法的 divSpotForm 行相关。我是否正确地将表单数据传递给操作?我想我的方法可能过于复杂,而不是直接从表单组件发布。

enter image description here

enter image description here

表单组件

 const [spot, setSpot] = useState({
        diveLocation: "",
        diveRegionID: parseInt(``),
        diveTypeID: parseInt(``),
        diveSpotDescription: "",
        diveSpotPhotos: "",
        error: ''
    });

    // all onChange functions do the exact same thing, so you only need one
    // pass to a component like onChange={handleChange('typeID')}
    const handleChange = (property) => (e) => {
        setSpot({
            // override the changed property and keep the rest
            ...spot,
            [property]: e.target.value,
        });
    }

    // get access to dispatch
    const dispatch = useDispatch();

    // useEffect with an empty dependency array is the same as componentDidMount
    useEffect(() => {
        dispatch(requireFieldData());
    }, []);

    const handleSubmitDiveSpot = () => {

        const diveSpotForm = new FormData(document.querySelector("diveSpotForm"))
        console.log('diveSpotForm', diveSpotForm);

        const diveSpot = {
            diveLocation: spot.diveLocation || undefined,
            diveRegionID: spot.diveRegionID || undefined,
            diveSpotTypeID: spot.diveSpotTypeID || undefined,
            diveSpotDescription: spot.diveSpotDescription || undefined,
            diveSpotPhotos: spot.diveSpotPhotos || undefined
        }

        // do some stuff with the form
        createDiveSpot(diveSpot).then((data) => {
            const newSpot = data.error
                ? {...spot, error: data.error}
                : {...spot, error: '', open: true};
            setSpot(newSpot);
            dispatch(addDiveSpot(newSpot));
        })
    }


    const classes = useStyles;

    return (

        <form className="diveSpotForm" method="POST" encType="multipart/form-data" onSubmit={handleSubmitDiveSpot}>
            <>
                <Grid container spacing={3}
                      direction="row"
                      justify="center"
                      alignItems="center">
                    <Grid item xs={4}>
                    <FormControl className={classes.formControl}>
                        <PopulateDropdown
                            dataList={diveTypeList}
                            titleProperty={"diveType"} // option label property
                            valueProperty={"diveTypeID"} // option value property
                            name="diveType"
                            placeholder="Dive Type"
                            label="Select Dive Type"
                            value={spot.diveTypeID}
                            onChange={handleChangeInt(parseInt("diveTypeID"))}/>
                    </FormControl>
                    </Grid>
                    <br />
                   ........

                    <br />
                    <Grid item xs={10}>
                        <FormControl fullWidth className={classes.margin}>
                            <TextField
                                label="Description"
                                name="diveSpotDescription"
                                value={spot.diveSpotDescription}
                                onChange={handleChange("diveSpotDescription")}
                                multiline
                                rowsMax={6}/>
                        </FormControl>
                    </Grid>
                    <br />
                    <Grid item xs={12}>
                        <FormControl fullWidth className={classes.margin}>
                            <label for="photos">Photo Upload</label>
                            <input
                                type="file"
                                name="photo"
                                value={spot.diveSpotPhotos}
                                onChange={handleChange("diveSpotPhotos")}/>
                        </FormControl>
                    </Grid>
                    <br />
                    <Grid item xs={3}>
                        <Button variant="primary" type="submit">
                            Submit</Button>
                        <br />
                    </Grid>
                </Grid>
            </>
        </form>

enter image description here

行动

export const createDiveSpot = async (diveSpot) => {
    try {
        let response = await fetch('http://localhost:5002/api/divespot/createdivespot', {
            method: 'POST',
            headers: {
                "Content-Type":"multipart/form-data"
            },
            body: new FormData(diveSpot)
        })
        return await response.json()
    } catch(err) {
        console.log(err)
    }
}

后端

exports.createDiveSpot = async (req, res) => {

    const fileNameWithExtension = `${req.file.filename}-${req.file.originalname}`
    const newPath = `./assets/diveSpot/${fileNameWithExtension}`

    fs.rename(req.file.path, newPath, function (err) {
            if (err) {
                console.log(err)
                res.send(500)
            }
            diveSpot.create({
                diveLocation: req.body.diveLocation,
                diveRegionID: req.body.diveRegionID,
                diveSpotTypeID: req.body.diveLocation,
                diveSpotDescription: req.body.diveSpotDescription,
                photos: fileNameWithExtension,
            })
                .catch((err) => {
                    res.status(500).send({
                        message: err.message || 'Some error occurred while creating the post.',
                    })
                })
        }
    )}

路线

app.post('/api/divespot/createdivespot', upload.single("diveSpotPhotos"), controller.createDiveSpot);

更新

我还尝试了下面的handleSubmit方法,它仍然显示相同的两个参数1不是对象错误。由于其中有两个,看起来可能是两个 id 字段(它们也没有出现在控制台中的有效负载请求中)。

function diveSpotForm(e: React.FormEvent<HTMLFormElement>) {
        e.preventDefault();
        const formData = new FormData();
        formData.append("diveLocation", spot.diveLocation);
        formData.append("diveRegionID", spot.diveRegionID);
        formData.append("diveSpotTypeID", spot.diveSpotTypeID);
        formData.append("diveSpotDescription", spot.diveSpotDescription);
        formData.append("photos", file);
        axios.post("http://localhost:5002/api/divespot/createdivespot", formData);
    }

最佳答案

如果没有完整的代码、可运行的项目等,很难弄清楚这一点......
但我可以在您的代码中发现一些问题。

  1. FormData 构造函数应该获取表单对象作为参数, 不是具有值的对象(并且您无缘无故地重新定义相同的 divSpot 变量 - 删除此let diverSpot = new FormData())。
    https://developer.mozilla.org/en-US/docs/Web/API/FormData/FormData

  2. 这是已修复的后端功能(至少是一次尝试)

 exports.createDiveSpot = async (req, res) => {
    try {
        console.log(req.diveSpot);

        // if (req.diveSpot == undefined) {
        //     return res.send(`You must select a file.`);
        // }

        return diveSpot.create({
            diveLocation: req.diveSpot.diveLocation,
            diveRegionID: req.diveSpot.diveRegionID,
            diveSpotTypeID: req.diveSpot.diveSpotTypeID,
            diveSpotDescription: req.diveSpot.diveSpotDescription,
            // You want the file location here 
            diveSpotPhotos: "/assets/" + req.file.filename
            ),
        }).then((diveSpot) => {
            fs.writeFileSync(
                __basedir + "/assets/" + req.file.filename,
                req.file.buffer
            );

            return res.json(`File has been uploaded.`);
        });
    } catch (error) {
        console.log(error);
        return res.send(`Error when trying upload images: ${error}`);
    }
};
  • 您的操作已修复(再次尝试)
  • export const createDiveSpot = async (diveSpot) => {
       return fetch('http://localhost:5002/api/divespot/createdivespot', {
                method: 'POST',
                headers: {
                    "Content-Type":"multipart/form-data"
                },
                body: new FormData(diveSpot)
            })
    .then(response => response.json())
    .catch(err => console.log(err));
           
    }
    

    关于node.js - 多部分表单组件 "cannot POST/divespotform"无法正常工作 parseInt 问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66847865/

    相关文章:

    javascript - 处理 GET 路由上的 POST 请求 (express.js)

    node.js - 什么是 Mongoose ODM 的 ObjectId?

    node.js - 使用 mongoose 显示 cloudinary 上传的图像

    node.js - 过滤包含在 sequelize 中

    node.js - Webpack Bundle.js 内容

    javascript - 如何通过工具 'read-excel-file' 在 ReactJS 上导入 excel?

    javascript - 在 '...0.0"附近解析时 JSON 输入意外结束 ,"acorn-globals":'

    javascript - Node.js 和 Jade

    javascript - 替换innerHTML后EventListener不起作用

    node.js - 出现错误通用类型 'InsertWriteOpResult<TSchema>' 需要 mongo 种子库中的 1 个类型参数