create-react-app 和节点服务器的 ECONNREFUSED 错误 [英] ECONNREFUSED error for create-react-app and node server

查看:52
本文介绍了create-react-app 和节点服务器的 ECONNREFUSED 错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 create-react-app(因此没有自定义 webpack)和节点服务器构建一个 MERN 应用程序.我正在使用 nodemon 重新启动后端的更改,问题是大约一半的时间我的前端似乎在 nodemon 可以重新启动节点服务器之前尝试呈现,从而导致 ECONNREFUSED 错误.

I'm builing a MERN application with create-react-app (so no custom webpack) and a node server. I'm using nodemon to restart changes on the backend, and the problem is that about half of the time it seems that my front-end tries to render before nodemon can restart the node server, resulting in a ECONNREFUSED error.

我只需刷新页面即可解决该问题,但必须重复执行此操作很烦人,我想弄清楚可能是什么问题.如果我运行节点服务器而不是 nodemon,则不会发生这种情况.

I can solve the issue my simply refreshing the page, but it's annoying to have to do this repeatedly and I'd like to just figure out what the issue may be. This isn't happening if I run node server instead of nodemon.

这是我的客户端 package.json 的相关部分:

Here's the relevant part of my client side package.json:

"scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject"
},
"proxy": "http://localhost:7777"

和服务器端package.json:

and the server side package.json:

"scripts": {
   "client-install": "npm intall --prefix client",
   "start": "node server.js",
   "server": "nodemon server.js",
   "client": "cd client && npm start",
   "dev": "concurrently \"npm run server\" \"npm run client\""
}

和我的 server.js

and my server.js

const express = require('express');
const bodyParser = require('body-parser');
const mongoose = require('mongoose');
const path = require('path');
const routes = require('./routes/index');
require('dotenv').config();

const app = express();

app.use(bodyParser.json());

mongoose.connect(process.env.DATABASE, {useNewUrlParser: true})
    .then(() => console.log('MongoDb connected'))
    .catch(err => console.log(`Mongo error ${err}`))

const port = process.env.PORT || 7777;

app.use('/', routes);

if (process.env.NODE_ENV === 'production') {
    // Serve any static files
    app.use(express.static(path.join(__dirname, 'client/build')));
    // Handle React routing, return all requests to React app
    app.get('*', function(req, res) {
    res.sendFile(path.join(__dirname, 'client/build', 'index.html'));
    });
}

app.listen(port, () => {
    console.log(`Connected at port ${port}`)
})

我在前端 HTTP 请求中使用 axios:

I'm using axios for my front-end HTTP requests:

import axios from 'axios';
import FormData from 'form-data'
import keys from '../keys';

export const getPosts = () => {
    return axios.get('/api')
}
export const post = (file, bodyInfo) => {
    let formData = new FormData();
    formData.append('file', file[0], file[0].name);
    formData.append('bodyInfo', JSON.stringify(bodyInfo));
    return axios.post('/api', formData, {
        headers: {
            'Content-Type': `multipart/form-data; 
              boundary=${formData._boundary}`,
          }
    })
}
export const getSinglePhoto = (id) => {
    return axios.get(`/api/${id}`);
}
export const postUser = (userDetails) => {
    console.log(userDetails);
    return axios.post('/api/user', userDetails)
}
export const getUser = () => {
    return axios.get('/user');
}
export const removeUser = (id) => {
    return axios.delete(`/user/${id}`)
}

这是我的路线:

router.get('/api', postController.getPosts);
router.post('/api', 
    postController.type, 
    postController.uppic,
    postController.cloudinary
);
router.get('/api/:id', postController.getSingle);
router.get('/user', userController.getUser);
router.post('/api/user', userController.postUser);
router.delete('/user/:id', userController.removeUser);

推荐答案

尝试使用 CORS 而不是 package.json 代理.我记得当我使用一个时遇到随机/间歇性连接问题.简而言之:前端在端口 3000 上运行,express API 在 5000 上运行.编译后,都运行在 5000express 上,为编译后的前端 js 提供服务,就像一个 API.

Try using CORS instead of a package.json proxy. I remember having random/intermittent connection issues when I used one. In short: Front-end runs on port 3000 and express API runs on 5000. When compiled, both run on 5000 and express serves the compiled front-end js and acts like an API.

非常相似的设置,但没有连接问题:

Very similar set up, but no connection problems:

express server package.json

...
"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "NODE_ENV=production node app.js",
    "server": "NODE_ENV=development nodemon app.js",
    "client": "npm run start --prefix client",
    "dev": "concurrently \"npm run server\" \"npm run client\"",
    "seeds": "NODE_ENV=development node seeds.js"
},
...

client/package.json(使用 sass 编译器,您可以使用/忽略).

client/package.json (using a sass compiler, which you can use/ignore).

...
"scripts": {
    "build-css": "node-sass-chokidar --include-path ./src --include-path ./node_modules src/ -o src/",
    "watch-css": "npm run build-css && node-sass-chokidar src/ -o src/ --watch --recursive",
    "start-js": "react-scripts start",
    "start": "npm-run-all -p watch-css start-js",
    "build": "npm run build-css && react-scripts build",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject"
},
...

client/src/actions/axiosConfig.js(然后我创建一个 axios 配置以自动指向我在 5000 上运行的 Express API)

client/src/actions/axiosConfig.js (then I create an axios config to automatically point to my Express API running on 5000)

import axios from 'axios';

export const app = axios.create({
    baseURL: 'http://localhost:5000/api/',
    withCredentials: true
})

client/src/actions/authActions.js(然后导入 axios 配置)

import { app } from './axiosConfig';

const signinUser = props => dispatch => (
    app.post(`signin`, { ...props })
    .then(({data}) => {
        dispatch({ type: types.SET_SIGNEDIN_USER, payload: data })
        dispatch(fetchAvatarOnLogin());
    })
    .catch(err => dispatch({ type: types.SERVER_ERROR, payload: err }))
);

express server.js(我使用consign导入所有文件):

express server.js (I use consign to import all the files):

const express   = require('express');
const app       = express();
const consign   = require('consign');

consign({ locale: 'en-us', verbose: false})
    .include('libs/middlewares.js')
    .then("database")
    .then("shared")
    .then("services")
    .then("controllers")
    .then("routes")
    .then('libs/server.js')
    .into(app);

然而,等价物是:

// APP REQUIRED IMPORTS
const express   = require('express');
const app       = express();
...etc

// APP MIDDLEWARES
...
app.use(cors({credentials: true, origin: http://localhost:3000})) // allows receiving of cookies from front-end
app.use(morgan('tiny')); // logging framework
app.use(bodyParser.json()); // parses header requests (req.body)
app.use(bodyParser.urlencoded({ extended: true })); // allows objects and arrays to be URL-encoded
...etc

// DATABASE CONFIG/CONN


// APP SHARED FUNCS


// APP SERVICES (passport, sendgrid mailer, ...etc)


// APP CONTROLLERS
...
signin: (req, res, done) => passport.authenticate('local-login', err => (
        (err || !req.session) ? sendError(err || badCredentials, res, done) : res.status(201).json({ ...req.session }))
    )(req, res, done)
...etc

// APP ROUTES
...
app.post('/api/signin', signin);
...etc

// EXPRESS SERVER
if (process.env.NODE_ENV === 'production') {
    app.use(express.static('client/build'));   

    app.get('*', (req, res) => res.sendFile(path.resolve('client', 'build', 'index.html')));
}

app.listen(5000);

这篇关于create-react-app 和节点服务器的 ECONNREFUSED 错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆