无法代理请求。但是数据正在保存在数据库中,相互影响并做出反应

时间:2020-08-11 09:51:10

标签: reactjs express redux multer

这让我发疯。我现在调试了一个星期,仍然无法修复此代理错误。但是有一个陷阱。我在api端点中发送的数据仍保存在数据库中。

这就是我得到的。

我有一个react组件,可以处理公告的输入。该组件还处理文件上传。

import React, { useState, useEffect } from 'react';
import { connect } from 'react-redux';
import { addAnnouncement } from '../../actions/announcementActions';
import moment from 'moment';
function AddEventForm(props){
    const classes = styles();

    /* States*/

    const [values, setValues] = useState({
        title: '',
        venue: '',
        description: '',
        bgColor:'#000000',

    });

    const [poster, getPoster] = useState({
        poster: null,
        fileName: ''
    });

     const [selectedDate, setSelectedDate] = useState(new Date());
     const [selectedTime, setSelectedTime] = useState(new Date());

     const [errors, getErrors] = useState({});
    
    /* Event Handlers*/
    const handleDate = date => {
        setSelectedDate(date);
    }

    const handleTime = time => {
        setSelectedTime(time);
    }


    const handleSubmit = e => {
        e.preventDefault();

        // const fullDate = `${selectedDate.getFullYear()}-${selectedDate.getMonth() + 1}-${selectedDate.getDate()}`;
        const dateDate = moment(selectedDate).format('YYYY-MM-DD');
        const dateTime = moment(selectedTime).format('HH:mm:ss');       

        const date = `${dateDate} ${dateTime}`;

        const newAnnouncement = { 
            ...values,
            ...poster,
            date,
            dateDate,
            dateTime,
            setBy: 'SOA Admin'
        }

        let fd = new FormData();
        fd.append('poster', poster.poster);
        fd.append('title', values.title);
        fd.append('venue', values.venue);
        fd.append('description', values.description);
        fd.append('fileName', poster.fileName);
        fd.append('bgColor', values.bgColor);
        fd.append('date', date);
        fd.append('dateDate', dateDate);
        fd.append('dateTime', dateTime);
        fd.append('setBy', 'SOA Admin');

        // console.log(newAnnouncement);
        // console.log(_formData);
        props.addAnnouncement(fd);

    }

    // Component Effect for a successful Adding of Announcement
    useEffect(_ => {
       if(props.announcement.added)
          props.history.push('/ad/announceevent');

    },[props.announcement.added]);

    // Component Effect for the errors
    useEffect(_ => {
      if(props.errors)
          getErrors(props.errors)
    },[props.errors])

    console.log(props);
 
    return (
        <div>
            <DashboardAdmin>

            <Breadcrumbs aria-label="breadcrumb"  style={{ paddingBottom: '20px'}}>
                <Link color="inherit" href="/ad/announceevent" className={classes.link}>
                  <ViewListIcon className={classes.icon} />
                  Menu
                </Link>

                <Link
                  color="textPrimary"
                  href="/ad/announceevent/addevent"
                  aria-current="page"
                  className={classes.link}
                >
                <ListAltIcon className={classes.icon} />
                  Add
                </Link>
            </Breadcrumbs>

                <Paper className={classes.root}>
                      
                            <Container maxWidth="lg">

                              <Typography variant="h4" align="center">
                                    Announce Event Form
                                </Typography>
                                  <br></br>

                                <form noValidate onSubmit={handleSubmit} enctype="multipart/form-data">

                                <Typography variant="h6">
                                 Input the details needed.
                                </Typography>

                                    <Grid item xs={12}>
                                        <TextField 
                                        value={values.title}
                                        onChange={e => setValues({...values, title: e.target.value})}
                                            id="title"
                                            name="title"
                                            label="Announcement/Event Title"
                                            fullWidth
                                            autoComplete
                                        />
                                    </Grid>
                                    <span style={{ color: "red" }}>
                                           {errors.title}
                                     </span>
                                    <br />
                                     <Grid item xs={12}>
                                        <FormControl fullWidth className={classes.formControl}>
                                            <MuiPickersUtilsProvider utils={DateFnsUtils}>
                                                    <KeyboardDatePicker
                                                      value={selectedDate}
                                                      onChange={handleDate}
                                                      disableToolbar
                                                      variant="inline"
                                                      format="yyyy-MM-dd"
                                                      margin="normal"
                                                      id="date-picker-inline"
                                                      label="Date of the event"
                                                      KeyboardButtonProps={{
                                                        'aria-label': 'change date',
                                                      }}
                                                    />
                                            </MuiPickersUtilsProvider>
                                      </FormControl>
                                    </Grid>
                                     <span style={{ color: "red" }}>
                                           {errors.date}
                                     </span>
                                    
                                    <br />

                                     <Grid item xs={12}>
                                        <FormControl fullWidth className={classes.formControl}>
                                            <MuiPickersUtilsProvider utils={DateFnsUtils}>
                                                <KeyboardTimePicker
                                                 format= "hh:mm a"
                                                  value={selectedTime}
                                                  onChange={handleTime}
                                                  margin="normal"
                                                  id="time-picker"
                                                  label="Time picker"
                                                  KeyboardButtonProps={{
                                                    'aria-label': 'change time',
                                                  }}
                                                  keyboardIcon={<AccessTimeIcon />}
                                                />
                                            </MuiPickersUtilsProvider>
                                        </FormControl>
                                     </Grid>
                                     <br/>

                                    <Grid item xs={12}>
                                        <TextField 
                                            value={values.venue}
                                            onChange={e => setValues({...values, venue: e.target.value})}
                                            id="venue"
                                            name="venue"
                                            label="Where the event will happen"
                                            fullWidth
                                            autoComplete
                                        />
                                    </Grid>
                                     <span style={{ color: "red" }}>
                                           {errors.venue}
                                     </span>
                                    <br />

                            <Grid container spacing={1} alignItems="flex-end">

                                <Grid item xs={1}>

                                  {/* 
                                     onChange={e => setObj({...obj, file: e.target.files[0], fileName: e.target.files[0].name})} 

                                    value={obj.fileName}

                                  */}
                                    <input
                                    onChange={e => getPoster({...poster, poster: e.target.files[0], fileName: e.target.files[0].name.toLowerCase().split(' ').join('-')})} 
                                    className={classes.input} id="poster" name="poster" type="file" />
                                      <label htmlFor="poster">
                                        <IconButton color="primary" aria-label="upload picture" component="span">
                                          <CloudUploadIcon />
                                        </IconButton>
                                     </label>

                                  </Grid>

                                  <Grid item xs={11}>
                                    <TextField 
                                    value={poster.fileName}
                                    id="input-with-icon-grid"
                                    label="Poster for the event"
                                    helperText="Note: .png and .jpg is required"
                                    fullWidth
                                      InputProps={{
                                           readOnly: true,
                                          }}
                                       InputLabelProps={{
                                            shrink: true,
                                       }}
                                    />
                                </Grid>
                            </Grid>
                             <span style={{ color: "red" }}>
                                           {errors.poster}
                                     </span>

                            <br />

                            <Grid container spacing={1} alignItems="flex-end">

                            <Grid item xs={8}>
                                  <TextField 
                                        value={values.description}
                                        onChange={e => setValues({...values, description: e.target.value})}
                                            id="description"
                                            name="description"
                                            label="Description of the Event"
                                            fullWidth
                                            autoComplete
                                            multiline
                                        />
                                </Grid>
                               
                                <br/>
                                  <span style={{ color: "red" }}>
                                           {errors.description}
                                     </span>

                                <Grid item xs={4}>
                                        <TextField 
                                        type="color"
                                        value={values.bgColor}
                                        onChange={e => setValues({...values, bgColor: e.target.value})}
                                            id="color"
                                            name="color"
                                            label="Choose color for the display background of the event"
                                            fullWidth
                                            autoComplete
                                        />
                                    </Grid>

                                </Grid>

                                <Button
                                    type="submit"
                                    variant="outlined"
                                    color="secondary"
                                    className={classes.submit}
                                >
                                    Add Record
                                </Button>

                                    
                                </form>

                            </Container>

                </Paper>
            </DashboardAdmin>
        </div>
    )
}

  const mapStateToProps = state => ({
  announcement: state.announcement,
  errors: state.errors,
});

const mapDispatchToProps = { addAnnouncement }; 

export default connect(mapStateToProps, mapDispatchToProps)(AddEventForm);

然后这就是我的动作

export const addAnnouncement = data => dispatch => {
    axios.post('/api/announcements/addEvents', data)
    .then(res => dispatch({
        type: ADD_ANNOUNCEMENT_ADMIN,
        payload: res.data,
    }))
    .catch(err => dispatch({
        type: GET_ERRORS,
        payload: err.response.data
    }));
}

那么这就是减速器

import {
    ADD_ANNOUNCEMENT_ADMIN,

} from '../actions/types';

const initialState = {
    added: false,
};

const initialState = {
    added: false,
    updated: false,
    deleted: false,
};

export default function(state = initialState, action) {
    switch(action.type) {
        case ADD_ANNOUNCEMENT_ADMIN:
            return {
                ...state,
                added:true
            };
        //....

        default: 
            return state;
    }   
};

这是我到达api端点/ addEvents

的路线
const express = require('express');
const router = express.Router();

const multer = require('multer');
const path = require('path');

//The directory where the files will be stored
const DIR = 'client/public/announcements/';

const Announcements = require('../../models/announcements.model');

const validateAnnouncements = require('../../validation/announcements');

//Diskstorage for sending the files into the assigned Directory
const storage = multer.diskStorage({
    // The destination of the file 
    destination: (req, file, cb) => {
        cb(null, DIR)
    },
    // what will be the filename of the file uploaded
    filename: (req, file, cb) => {

        // the filename format 
        const filename = file.originalname.toLowerCase().split(' ').join('-');

        cb(null, `${filename}`);
    }

});


const upload = multer({
     storage: storage,
       fileFilter: (req, file, cb) => {
            if(file.mimetype === 'image/jpg' || file.mimetype === 'image/jpeg' || file.mimetype === 'image/png') {  
                cb(null, true)
            } 
            else {
        
             cb(null, false)
            }
 
       }
});

//@route POST /api/announcements/addEvents
//@desc Add a announcements data
//@access SOA Admin and SOA Head
router.post('/addEvents', upload.single('poster'), (req, res) => {
    const poster = req.file;

    //Url of the app
    const url = req.protocol + '://' + req.get('host');

    const today = new Date();

    const { errors, isValid } = validateAnnouncements(req.body);

    if(!isValid) {
        return res.status(400).json(errors);
    }
    else if(poster === undefined) {
        return res.status(400).json({poster: 'Pictures only'})
    }
    else {

    const title = req.body.title;
    
    const date = req.body.date;

    const dateDate = req.body.dateDate;
    const dateTime = req.body.dateTime;
    const venue = req.body.venue;
    const description = req.body.description;
    const backgroundColor = req.body.bgColor;
    const setBy = req.body.setBy;
    const fileName = req.body.fileName;

    const newAnnouncements = new Announcements({
        title,
        date,
        dateDate,
        dateTime,
        backgroundColor,
        venue,
        description,
        poster: url + '/' + poster.path,
        fileName,
        setBy,
        created_at: today
    });

    newAnnouncements.save()
    .then(response => res.json({
        message:'Request submitted',
        datas: {response}
    }))
    .catch(err => res.status(500).json(err));   
    }

    // console.log(newAnnouncements);

});

我不知道我的应用出现代理错误的原因。

这是错误消息

Proxy error: Could not proxy request /api/announcements/addEvents from localhost:8000 to http://localhost:6000.
[1] See https://nodejs.org/api/errors.html#errors_common_system_errors for more information (ECONNRESET).

这是我在react中的package.json

{
  "name": "client",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@date-io/date-fns": "^1.3.13",
    "@fullcalendar/core": "^5.1.0",
    "@fullcalendar/daygrid": "^5.1.0",
    "@fullcalendar/interaction": "^5.1.0",
    "@fullcalendar/react": "^5.1.0",
    "@material-ui/core": "^4.7.1",
    "@material-ui/icons": "^4.5.1",
    "@material-ui/lab": "^4.0.0-alpha.48",
    "@material-ui/pickers": "^3.2.10",
    "@material-ui/system": "^4.9.6",
    "axios": "^0.19.2",
    "classnames": "^2.2.6",
    "fullcalendar": "^5.1.0",
    "jwt-decode": "^2.2.0",
    "moment": "^2.24.0",
    "react": "^16.12.0",
    "react-dom": "^16.12.0",
    "react-redux": "^7.2.0",
    "react-router-dom": "^5.1.2",
    "react-scripts": "^3.4.1",
    "redux": "^4.0.5",
    "redux-thunk": "^2.3.0"
  },
  "scripts": {
    "start": "PORT=8000 react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "proxy": "http://localhost:6000",
  "eslintConfig": {
    "extends": "react-app"
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}

这使我花了一个星期来调试它,但仍然无法解决为什么它出现代理错误。感觉像是客户端崩溃了。但是仍然在保存数据。然后,它只会刷新应用程序本身。

提供有关如何解决此问题的建议和帮助,将不胜感激。

0 个答案:

没有答案