I have a multipart form that I am nearly finished working on that is still not posting to my backend database. If I am getting cors errors would this be to do with the POST not going from the frontend 5001 server to the backend 5002 server? What usually causes this?
There is also likely errors in my service method when I post multipart form data with Axios (createDiveSpot). Am I ok posting this all on the one route? I think my backend route handles storing the image and sending the url to the controller ok.
error message
POSThttp://localhost:5001/divespotform [HTTP/1.1 404 Not Found 14ms] Content Security Policy: The page's settings blocked the loading of a resource at inline ("default-src"). pagewrap.bundle.js:1:1151 Content Security Policy: The page's settings blocked the loading of a resource at inline ("default-src"). injectGlobalHook.js:808:49 Content Security Policy: The page's settings blocked the loading of a resource at http://localhost:5001/favicon.ico ("default-src"). FaviconLoader.jsm:191:19 Content Security Policy: The page's settings blocked the loading of a resource at inline ("default-src")
form component
const [spot, setSpot] = useState({ diveLocation: "", diveRegionID: "", diveTypeID: "", 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 = () => { let diveSpot = new FormData() 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) => { if (data.error) { setSpot({ ...spot, error: data.error}) } else { setSpot({ ...spot, error: '', open: true}) } }) // do we need to save this to the backend? or just to redux? dispatch(addDiveSpot(spot)); } const classes = useStyles; return ( // <AppBar title="Enter your dive details"></AppBar> <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}> ........ <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>
action
export const createDiveSpot = async (diveSpot) => { try { let response = await fetch('/api/divespot/createdivespot', { method: 'POST', headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' }, body: JSON.stringify(diveSpot) }) return await response.json() } catch(err) { console.log(err) } }
service
export const **createDiveSpot** = (diveSpotID, diveLocation, diveRegionID, diveSpotTypeID, diveSpotDescription, diveSpotPhotos) => { let formData = new FormData(); formData.append("diveSpotPhotos", diveSpotPhotos); return http.post(API_URL + "createdivespot", { headers: { "Content-Type": "multipart/form-data", }, }); };
Backend
route
app.post('/api/divespot/createdivespot',upload.single("diveSpot"), controller.createDiveSpot);
controller
exports.createDiveSpot = async (req, res) => { try { console.log(req.diveSpot); if (req.diveSpot == undefined) { return res.send(`You must select a file.`); } diveSpot.create({ diveLocation: req.diveSpot.diveLocation, diveRegionID: req.diveSpot.diveRegionID, diveSpotTypeID: req.diveSpot.diveSpotTypeID, diveSpotDescription: req.diveSpot.diveSpotDescription, diveSpotPhotos: fs.readFileSync( __basedir + "/static/assets/" + req.file.filename ), }).then((diveSpot) => { fs.writeFileSync( __basedir + "/static/assets/" + diveSpot.diveLocation, diveSpot.diveSpotPhotos ); return res.send(`File has been uploaded.`); }); } catch (error) { console.log(error); return res.send(`Error when trying upload images: ${error}`); } };
multer
const multer = require("multer"); // config for multer to disk storage engine const imageFilter = (req, file, cb) => { if (file.diveLocation.startsWith("image")) { cb(null, true); } else { cb("Please upload only images.", false); } }; //sustscub timestamp prefix to stop duplicates const storage = multer.diskStorage({ destination: (req, file, cb) => { cb(null, __basedir + "/static/assets/uploads/"); }, filename: (req, file, cb) => { cb(null, `${Date.now()}-SustScub-${file.originalname}`); }, }); // filter only allows images to pass const uploadFile = multer({ storage: storage, fileFilter: imageFilter }); module.exports = uploadFile;
https://stackoverflow.com/questions/66847865/multipart-form-component-cannot-post-divespotform-not-working-cors-issue March 29, 2021 at 09:56AM
没有评论:
发表评论