React / Nodejs:前端和后端的URL不匹配,这会导致错误

时间:2019-06-03 06:50:47

标签: node.js reactjs redux

我想在我的应用程序中创建一个公共配置文件页面,但是每当我碰到一条路线时,控制台中都会出现错误。我不明白这是什么问题,请您换个新的眼睛看看。让我给您更多有关我的问题的信息。

公共路线-后端

// @route  POST api/profile/user/:user_id
// @desc   Get profile by user ID
// @access Public
router.get('/user/:user_id', (req, res) => {
  const errors = {};
  Profile.findOne({ user: req.params.user_id })
    .populate('user', ['name', 'email', 'avatar'])
    .then(profile => {
      if (!profile) {
        errors.nonprofile = 'There is no profile for this user';
        res.status(404).json(errors);
      }
      res.json(profile);
    })
    .catch(err =>
      res.status(404).json({ profile: 'There is no profile for this user' })
    );
});

Redux动作部分

export const getPublicProfileByID = id => dispatch => {
  console.log(id);
  axios
    .get(`api/profile/user/${id}`)
    .then(res => {
      dispatch({
        type: GET_PUBLIC_PROFILE_BY_ID,
        payload: res.data
      });
    })
    .catch(err =>
      dispatch({
        type: GET_PUBLIC_PROFILE_BY_ID,
        payload: null
      })
    );
};

PublicProfile-反应部分

import React, { Component } from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import Spinner from '../common/Spinner';
import { getPublicProfileByID } from '../../actions/profileActions';
import { Link } from 'react-router-dom';

class PublicProfile extends Component {
  constructor(props) {
    super(props);
  }

  componentDidMount() {
    console.log(this.props);
    this.props.getPublicProfileByID(this.props.profile._id);
  }

  render() {
    const { profile, loading } = this.props.profile;
    const { auth } = this.props;
    console.log(profile);
    let profileShow;

    if (profile === null || loading) {
      profileShow = <Spinner />;
    } else {
      profileShow = (
        <div className="row">
          <div className="col-md-4" align="center">
            <figure className="figure">
              <img
                src={auth.user.avatar}
                className="figure-img img-fluid rounded"
                alt={auth.user.avatar}
              />
            </figure>
          </div>
          <div className="col-md-6">{profile.bio}</div>
          <div className="col-md-2">
            <ul className="list-group list-group-flush">
              <li className="list-group-item">
                <div className="row">
                  <div className="col">
                    {profile.social ? (
                      <a href={profile.social.facebook} target="_blank">
                        <i className="fab fa-facebook" />
                      </a>
                    ) : null}
                  </div>
                  <div className="col">
                    {profile.social ? (
                      <a href={profile.social.vk} target="_blank">
                        <i className="fab fa-vk" />
                      </a>
                    ) : null}
                  </div>
                  <div className="col">
                    {profile.social ? (
                      <a href={profile.social.instagram} target="_blank">
                        <i className="fab fa-instagram" />
                      </a>
                    ) : null}
                  </div>
                </div>
              </li>
              {profile.country ? (
                <li className="list-group-item">Страна: {profile.country}</li>
              ) : null}
              {profile.city ? (
                <li className="list-group-item">Город: {profile.city}</li>
              ) : null}
              {profile.gender ? (
                <li className="list-group-item">Пол: {profile.gender}</li>
              ) : null}
              {profile.education ? (
                <li className="list-group-item">
                  Образование: {profile.education}
                </li>
              ) : null}
              {profile.languages ? (
                <li className="list-group-item">
                  Языки:{' '}
                  {profile.languages.map(language => (
                    <span key={language}>{language}</span>
                  ))}
                </li>
              ) : null}
            </ul>
          </div>
        </div>
      );
    }

    return (
      <div className="container">
        <div className="row">
          <div className="col align-self-center">{profileShow}</div>
        </div>
      </div>
    );
  }
}

PublicProfile.propTypes = {
  auth: PropTypes.object.isRequired,
  getPublicProfileByID: PropTypes.func.isRequired
};

const mapStateToProps = state => ({
  profile: state.profile,
  auth: state.auth
});

export default connect(
  mapStateToProps,
  { getPublicProfileByID }
)(PublicProfile);

Redux Reducer零件

import {
  GET_PROFILE,
  PROFILE_LOADING,
  CLEAR_CURRENT_PROFILE,
  GET_PUBLIC_PROFILE_BY_ID
} from '../actions/types';

const initialState = {
  profile: null,
  profiles: null,
  loading: false
};

export default function(state = initialState, action) {
  switch (action.type) {
    case PROFILE_LOADING:
      return {
        ...state,
        loading: true
      };
    case GET_PROFILE:
      return {
        ...state,
        profile: action.payload,
        loading: false
      };
    case GET_PUBLIC_PROFILE_BY_ID:
      return {
        ...state,
        profile: action.payload,
        loading: false
      };
    case CLEAR_CURRENT_PROFILE:
      return {
        ...state,
        profile: null
      };
    default:
      return state;
  }
}

app.js中的公开路线

<Route exact path="/leaders/:id" component={PublicProfile} />

浏览器中的URL enter image description here

控制台中的错误 enter image description here

3 个答案:

答案 0 :(得分:1)

您将前端URL与后端Restful http URL混淆了, 您需要为React和Node App启动不同的两个端口, 您正在将React-Route逻辑与node-Express逻辑混合在一起, 当localhost:3000代表反应时,
您应该为后端应用程序选择其他端口号, 保持服务器监听该端口, 然后要求该网址并传达您的数据。 您需要正确配置您的应用。
例如。
localhost:3000/leaders/leader/2为您的前端, 发出服务器请求,例如 localhost:8000/api/profile/user/2,其中2为后端${id}

答案 1 :(得分:1)

我注意到,在您的api路由中,只有一个问题想要找到Profile字段与您传递的参数相匹配的user

router.get('/user/:user_id', (req, res) => {
  const errors = {};
  Profile.findOne({ user: req.params.user_id })

但是,看起来您在动作创建者中传递了错误的值。您正在传递配置文件的ID。

  componentDidMount() {
    console.log(this.props);
    this.props.getPublicProfileByID(this.props.profile._id);
  }

相反,您需要传递拥有此个人资料的用户的ID。

  componentDidMount() {
    console.log(this.props);
    this.props.getPublicProfileByID(this.props.profile.user._id);
  }

第二,您的axios通话似乎有误

  axios
    .get(`api/profile/user/${id}`)

答案 2 :(得分:0)

我已经解决了这个问题,应该使用findById方法,而参数应该是req.params.id。因此,有效的代码如下所示。

// @route  POST api/profile/user/:user_id
// @desc   Get profile by user ID
// @access Public

router.get('/user/:id', (req, res) => {
  const errors = {};
  Profile.findById(req.params.id)
    .populate('user', ['name', 'email', 'avatar'])
    .then(profile => {
      if (!profile) {
        errors.nonprofile = 'There is no profile for this user';
        res.status(404).json(errors);
      }
      res.json(profile);
    })
    .catch(err =>
      res.status(404).json({ profile: 'There is no profile for this user' })
    );
});