2021年3月28日星期日

Multipart form component "cannot POST / divespotform" not working - CORS issue

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")  

enter image description here

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

没有评论:

发表评论