首页 > 解决方案 > 发布到我的网站时出现内部服务器错误,但在删除帖子时没有

问题描述

我似乎无法弄清楚我的服务器如何无法满足发布请求。当我在下面提供这个 JSON 时,它在邮递员中工作得很好

{ "name": "post11111111111", "images": "image/path", "link": "https://etsy.com", "info": "this is a painting", "price": "75", "itemCategory": "painting", "available": "true", "highEnd": "false" }

但是在我的客户端程序中使用 axios 发出 post 请求时,它返回 500 错误。奇怪的是删除(和getAll)工作得很好。这是一个使用 node/express/firebase 服务器的反应应用程序。我将在前端附加所有内容,例如我认为相关的操作和组件(我正在使用 react 和 redux 进行练习)。

数据操作.js

import { SET_POSTS, LOADING_DATA, DELETE_POST, POST_PRODUCT, SET_ERRORS, CLEAR_ERRORS, LOADING_UI } from "../types";
import axios from 'axios';
//GET ALL PRODUCTS
export const getPosts = () => dispatch => {
    dispatch({ type: LOADING_DATA });
    axios.get('/posts')
        .then(res => {
            dispatch({
                type: SET_POSTS,
                payload: res.data
            })
        })
        .catch(err => {
            dispatch({
                type: SET_POSTS,
                payload: []
            })
        })
}
//POST PRODUCT
export const postProduct = (newPost) => (dispatch) => {
    dispatch({ type: LOADING_UI });
    axios.post('/post', newPost)
        .then(res => {
            dispatch({
                type: POST_PRODUCT,
                payload: res.data
            })
            console.log("success");
            dispatch({ type: CLEAR_ERRORS })
        })
        .catch(err => {
            dispatch({
                type: SET_ERRORS,
                payload: err.response.data
            })
        })
}
//DELETE PRODUCT
export const deletePost = (postId) => (dispatch) => {
    axios.delete(`/post/${postId}`)
        .then(() => {
            dispatch({ type: DELETE_POST, payload: postId })
        })
        .catch(err => console.log(err))
}

dataReducer.js

import { SET_POSTS } from '../types';
import { LOADING_DATA, DELETE_POST, POST_PRODUCT/*, SET_POST*/ } from '../types';

const initialState = {
    posts: [],
    post: {},
    loading: false
};

export default function(state = initialState, action){
    switch(action.type){
        case LOADING_DATA:
            return {
                ...state,
                loading: true
            }
        case SET_POSTS:
            return{
                ...state,
                posts: action.payload,
                loading: false
            }
        case DELETE_POST:
            let index = state.posts.findIndex(post => post.postId === action.payload);
            state.posts.splice(index, 1);
            return {
                ...state
            }
        case POST_PRODUCT:
            return {
                ...state,
                posts: [action.payload, ...state.posts]
            }
        default:
            return state
    }
}

PostProduct.js

import React, { Component, Fragment } from "react";
import { withStyles } from "@material-ui/core/styles";
import PropTypes from "prop-types";
import MyButton from "../util/MyButton";

//MUI Stuff
import Button from "@material-ui/core/Button";
import TextField from "@material-ui/core/TextField";
import Dialog from "@material-ui/core/Dialog";
import DialogTitle from "@material-ui/core/DialogTitle";
import DialogContent from "@material-ui/core/DialogContent";
import DeleteOutline from "@material-ui/icons/DeleteOutline";
import CircularProgress from '@material-ui/core/CircularProgress';
import AddIcon from '@material-ui/icons/Add';
import CloseIcon from "@material-ui/icons/Close";
//REDUX
import { connect } from "react-redux";
import { postProduct } from "../redux/actions/dataActions";

const styles = {
  form: {
    textAlign: "center"
  },
  image: {
    margin: "20px auto 20px auto",
    width: "50px"
  },
  pageTitle: {
    margin: "10px auto 10px auto"
  },
  textField: {
    margin: "10px auto 10px auto"
  },
  button: {
    marginTop: 20,
    postition: "relative"
  },
  customError: {
    color: "red",
    fontSixe: "0.8rem",
    marginTop: 10
  },
  progress: {
    position: "absolute"
  },
  submitButton: {
      position: "relative"
  },
  progressSpinner: {
      position: 'absolute'
  },
  closeButton: {
      position: 'absolute',
      left: '90%',
      top: '10%'
  }
};

class PostProduct extends Component {
    state = {
        open: false,
        name: '',
        errors: {}
    };
    UNSAFE_componentWillReceiveProps(nextProps){
        if (nextProps.UI.errors) {
            this.setState({
                errors: nextProps.UI.errors
            })
        }
    }
    handleOpen = () => {
        this.setState({ open: true })
    }
    handleClose = () => {
        this.setState({ open: false })
    }
    handleChange = (event) => {
        this.setState({ [event.target.name]: event.target.value })
    }
    handleSubmit = (event) => {
        event.preventDefault();
        this.props.postProduct({ body: this.state.body })
    }
    render(){
        const { errors } = this.state;
        const { classes, UI: {loading }} = this.props;
        return (
          <Fragment>
            <MyButton onClick={this.handleOpen} tip="Post a Product">
              <AddIcon />
            </MyButton>
            <Dialog
              open={this.state.open}
              onClose={this.handleClose}
              fullWidth
              maxWidth="sm"
            >
              <MyButton
                tip="close"
                onClick={this.handleClose}
                tipClassName={classes.closeButton}
              >
                <CloseIcon />
              </MyButton>
              <DialogTitle>Post the new Product</DialogTitle>
              <DialogContent>
                <form onSubmit={this.handleSubmit}>
                  <TextField
                    name="name"
                    type="text"
                    lable="Post Product"
                    multiline
                    rows="3"
                    placeholder="name"
                    error={errors.body ? true : false}
                    helperText={errors.body}
                    className={classes.textFields}
                    onChange={this.handleChange}
                    fullWidth
                  />
                  <TextField
                    name="images"
                    type="text"
                    lable="image"
                    multiline
                    rows="3"
                    placeholder="image"
                    error={errors.body ? true : false}
                    helperText={errors.body}
                    className={classes.textFields}
                    onChange={this.handleChange}
                    fullWidth
                  />
                  <TextField
                    name="itemCategory"
                    type="text"
                    lable="Painting"
                    multiline
                    rows="3"
                    placeholder="Painting"
                    error={errors.body ? true : false}
                    helperText={errors.body}
                    className={classes.textFields}
                    onChange={this.handleChange}
                    fullWidth
                  />
                  <TextField
                    name="link"
                    type="text"
                    lable="link"
                    multiline
                    rows="3"
                    placeholder="https://etsy.com"
                    error={errors.body ? true : false}
                    helperText={errors.body}
                    className={classes.textFields}
                    onChange={this.handleChange}
                    fullWidth
                  />
                  <TextField
                    name="info"
                    type="text"
                    lable="blah blah blah"
                    multiline
                    rows="3"
                    placeholder="info"
                    error={errors.body ? true : false}
                    helperText={errors.body}
                    className={classes.textFields}
                    onChange={this.handleChange}
                    fullWidth
                  />
                  <TextField
                    name="price"
                    type="text"
                    lable="Price"
                    multiline
                    rows="3"
                    placeholder="75.99"
                    error={errors.body ? true : false}
                    helperText={errors.body}
                    className={classes.textFields}
                    onChange={this.handleChange}
                    fullWidth
                  />
                  <TextField
                    name="available"
                    type="text"
                    lable="available?"
                    multiline
                    rows="3"
                    placeholder="true"
                    error={errors.body ? true : false}
                    helperText={errors.body}
                    className={classes.textFields}
                    onChange={this.handleChange}
                    fullWidth
                  />
                  <TextField
                    name="highEnd"
                    type="text"
                    lable="High-end or not?"
                    multiline
                    rows="3"
                    placeholder="false"
                    error={errors.body ? true : false}
                    helperText={errors.body}
                    className={classes.textFields}
                    onChange={this.handleChange}
                    fullWidth
                  />
                  <Button
                    type="submit"
                    variant="contained"
                    color="primary"
                    className={classes.submitButton}
                    disabled={loading}
                  >
                    Submit
                    {loading && (
                      <CircularProgress
                        size={30}
                        className={classes.progressSpinner}
                      />
                    )}
                  </Button>
                </form>
              </DialogContent>
            </Dialog>
          </Fragment>
        );
    }


} // END CLASS

PostProduct.propTypes = {
    postProduct: PropTypes.func.isRequired,
    UI: PropTypes.object.isRequired
}

const mapStateToProps = (state) => ({
    UI: state.UI
})

export default connect(mapStateToProps, { postProduct })(withStyles(styles)(PostProduct))

前端代码在此存储库中:https ://github.com/jIrwinCline/planum-front 和后端:https ://github.com/jIrwinCline/planum-magic

谢谢你的帮助。我知道这是个大问题...


谢谢jfriend00!!!


谢谢,我克服了那个错误。我没有布置我想要的对象属性,而是在我的请求中添加了“body:this.state.body”。我实际上需要整个 JSON 内容。

现在我遇到了一个问题,即我实际上没有将任何提交的信息放入正在创建的卡中。让我知道你是否看到任何东西。

出现的一些错误是

index.js:1375 Material-UI: either `children`, `image` or `src` prop must be specified. 
    in CardMedia (created by WithStyles(ForwardRef(CardMedia)))
    in WithStyles(ForwardRef(CardMedia)) (at Post.js:55)
    in Post (created by WithStyles(Post))
    in WithStyles(Post) (created by Connect(WithStyles(Post)))
    in Connect(WithStyles(Post)) (at products.jsx:18)
    in products (created by Connect(products))
    in Connect(products) (created by Router.Consumer)
    in Router.Consumer (created by Route)
    in Route (at App.js:44)
    in App (at src/​index.js:6)
console.<computed> @ index.js:1375
r @ backend.js:6
CardMedia @ CardMedia.js:41
renderWithHooks @ react-dom.development.js:16295
updateForwardRef @ react-dom.development.js:18145
beginWork$1 @ react-dom.development.js:20170
beginWork$$1 @ react-dom.development.js:25699
performUnitOfWork @ react-dom.development.js:24646
workLoopSync @ react-dom.development.js:24622
performSyncWorkOnRoot @ react-dom.development.js:24211
(anonymous) @ react-dom.development.js:12263
unstable_runWithPriority @ scheduler.development.js:821
runWithPriority$2 @ react-dom.development.js:12209
flushSyncCallbackQueueImpl @ react-dom.development.js:12258
flushSyncCallbackQueue @ react-dom.development.js:12246
batchedUpdates$1 @ react-dom.development.js:24332
notify @ Subscription.js:23
notifyNestedSubs @ Subscription.js:65
handleChangeWrapper @ Subscription.js:70
dispatch @ redux.js:221
e @ VM889:1
(anonymous) @ index.js:11
dispatch @ redux.js:638
(anonymous) @ dataActions.js:25
Promise.then (async)
(anonymous) @ dataActions.js:23
(anonymous) @ index.js:8
(anonymous) @ redux.js:476
PostProduct.handleSubmit @ PostProduct.js:83
callCallback @ react-dom.development.js:337
invokeGuardedCallbackDev @ react-dom.development.js:386
invokeGuardedCallback @ react-dom.development.js:439
invokeGuardedCallbackAndCatchFirstError @ react-dom.development.js:454
executeDispatch @ react-dom.development.js:585
executeDispatchesInOrder @ react-dom.development.js:610
executeDispatchesAndRelease @ react-dom.development.js:713
executeDispatchesAndReleaseTopLevel @ react-dom.development.js:722
forEachAccumulated @ react-dom.development.js:694
runEventsInBatch @ react-dom.development.js:739
runExtractedPluginEventsInBatch @ react-dom.development.js:881
handleTopLevel @ react-dom.development.js:5834
batchedEventUpdates$1 @ react-dom.development.js:24342
batchedEventUpdates @ react-dom.development.js:1417
dispatchEventForPluginEventSystem @ react-dom.development.js:5930
attemptToDispatchEvent @ react-dom.development.js:6047
dispatchEvent @ react-dom.development.js:5950
unstable_runWithPriority @ scheduler.development.js:821
runWithPriority$2 @ react-dom.development.js:12209
discreteUpdates$1 @ react-dom.development.js:24359
discreteUpdates @ react-dom.development.js:1442
dispatchDiscreteEvent @ react-dom.development.js:5917
index.js:1375 Warning: Failed prop type: The prop `postId` is marked as required in `DeletePost`, but its value is `undefined`.
    in DeletePost (created by WithStyles(DeletePost))
    in WithStyles(DeletePost) (created by ConnectFunction)
    in ConnectFunction (at Post.js:51)
    in div (created by ForwardRef(CardContent))
    in ForwardRef(CardContent) (created by WithStyles(ForwardRef(CardContent)))
    in WithStyles(ForwardRef(CardContent)) (at Post.js:60)
    in div (created by ForwardRef(Paper))
    in ForwardRef(Paper) (created by WithStyles(ForwardRef(Paper)))
    in WithStyles(ForwardRef(Paper)) (created by ForwardRef(Card))
    in ForwardRef(Card) (created by WithStyles(ForwardRef(Card)))
    in WithStyles(ForwardRef(Card)) (at Post.js:54)
    in Post (created by WithStyles(Post))
    in WithStyles(Post) (created by ConnectFunction)
    in ConnectFunction (at products.jsx:18)
    in div (created by ForwardRef(Grid))
    in ForwardRef(Grid) (created by WithStyles(ForwardRef(Grid)))
    in WithStyles(ForwardRef(Grid)) (at products.jsx:22)
    in div (created by ForwardRef(Grid))
    in ForwardRef(Grid) (created by WithStyles(ForwardRef(Grid)))
    in WithStyles(ForwardRef(Grid)) (at products.jsx:21)
    in products (created by ConnectFunction)
    in ConnectFunction (created by Context.Consumer)
    in Route (at App.js:44)
    in Switch (at App.js:42)
    in div (at App.js:41)
    in Router (created by BrowserRouter)
    in BrowserRouter (at App.js:39)
    in Provider (at App.js:38)
    in ThemeProvider (at App.js:37)
    in App (at src/index.js:6)

标签: reactjsfirebaseexpressaxios

解决方案


在您的 axios 代码中,您是这样调用postProduct()的:

this.props.postProduct({ body: this.state.body })

当你给它这个时,你说邮递员工作:

{
  "name": "post11111111111",
  "images": "image/path",
  "link": "https://etsy.com",
  "info": "this is a painting",
  "price": "75",
  "itemCategory": "painting",
  "available": "true",
  "highEnd": "false"
}

不可能它们是相同的结构。Postman 请求中没有顶级body属性,Axios 版本中不存在所有其他顶级属性。


可能值得为这两个请求准​​确记录服务器上的传入请求,并且您应该能够立即看到两个请求之间的不同之处。


推荐阅读