0
votes

The React-Redux front end production server is running on port 3000 (localhost:3000). The node-expressjs server is running on port 5000 (localhost:5000); I've placed a "proxy" value in the client side package.json, and even tried a proxy value in the options field of the axios call. However, axios always ignores the proxy values, and uses the client-side production build server, to make the api call to the express backend which sensibly returns a 404 error.

client-side package.json

{
  "name": "my-app",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "axios": "^0.19.0",
    "mongoose": "^5.7.12",
    "react": "^16.8.6",
    "react-addons-css-transition-group": "^15.6.2",
    "react-dom": "^16.8.6",
    "react-redux": "^7.1.0",
    "react-router": "^5.0.1",
    "react-router-dom": "^5.1.2",
    "react-router-redux": "^4.0.8",
    "react-scripts": "3.0.1",
    "redux": "^4.0.4",
    "redux-thunk": "^2.3.0"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "proxy": "http://localhost:5000",
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },
  "devDependencies": {
    "concurrently": "^4.1.1"
  }
}

The action creator:

export const registerUser = (SignUpFormData) => dispatch => {
    const configs = {
        headers: {
          'Content-Type': 'application/json'
        },
        proxy: {
            host: "http://localhost:5000",
            port: 5000
        }
    };

    const requestBody = JSON.stringify({...SignUpFormData});

    axios.post('/api/users/register', requestBody, configs)
    .then(res => {
        dispatch({
            type: UserActions.USER_AWAITING_EMAIL_VERIFICATION,
            userInfo: res.data.userName,
            msg: res.data.msg,
        })
    })
    .catch(error => {
        dispatch(returnAuthErros(error.response.data.msg, error.response.status, 'USER_SIGNUP_FALIURE'));
        dispatch({
            type: UserActions.USER_SIGNUP_FALIURE,
            msg: error.response.data.msg
        });
    })
}

enter image description here

If any one can let me know if I'm actually tackling the problem, but my efforts just aren't fruitful, or I'm completely missing the point here. Cheers.

2

2 Answers

0
votes

Referring to this post I think you can do the following...

const instance = axios.create({
     proxy: {
       host: 'localhost',
       port: 5000
     }
})

instance.post('/api/users/register', requestBody, configs)
.then(res => {
    dispatch({
        type: UserActions.USER_AWAITING_EMAIL_VERIFICATION,
        userInfo: res.data.userName,
        msg: res.data.msg,
    })
})
.catch(error => {
    dispatch(returnAuthErros(error.response.data.msg, error.response.status, 'USER_SIGNUP_FALIURE'));
    dispatch({
        type: UserActions.USER_SIGNUP_FALIURE,
        msg: error.response.data.msg
    });
})

Update

After some testing on my app (same setup as above) and some reading, I found that this is a known issue with axios. I can confirm that is it still not working on the last version as of today 0.19.0

The way I solved this before even finding your question was to declare a global constant on the file I would use axios and just put that in the url...

const BASE_URL = "http://localhost:5000"

// some code...

// Example code
componentDidMount() {
    axios({
        method: 'GET',
        url: `${BASE_URL}/api/list-example`
    }).then(response => {
        console.log(response)
    }).catch( (err) => {
        console.log(err)
    })
}

I also found that there are other npm packages that try to solve the issue with the proxy, but I haven't tried them since they are 2 years old now...these are axios-https-proxy-fix and axios-proxy-fix

0
votes

This implementation works:

export const registerUser = (SignUpFormData) => dispatch => {
    const configs = {
        headers: {
          'Content-Type': 'application/json'
        },
        proxy: {
            host: '127.0.0.1',
            port: 5000
        },
        validateStatus: function(status) { return status >= 200 && status < 300}
    };

    const requestBody = JSON.stringify({...SignUpFormData});

    // console.log(requestBody);

    axios.post('/api/users/register', requestBody, {...configs, validateStatus: function(status) {return status >= 200 && status < 300}})
    .then(res => {
        dispatch({
            type: UserActions.USER_AWAITING_EMAIL_VERIFICATION,
            userInfo: res.data.userName,
            msg: res.data.msg,
        })
    })
    .catch(error => {
        dispatch(returnAuthErros(error.response.data.msg, error.response.data.errors, error.response.status, 'USER_SIGNUP_FALIURE'));
        dispatch({
            type: UserActions.USER_SIGNUP_FALIURE,
            msg: error.response.data.msg,
            authErrors: error.response.data.errors
        });
    })
} 

I found the adding the proxy config option as above resolved the 404 issue, but the validateStatus option doesn't affect the consequent 402 errors, which is can be easily resolved by changing what http status you return in your backend routes.