【问题标题】:ECONNREFUSED error for create-react-app and node servercreate-react-app 和节点服务器的 ECONNREFUSED 错误
【发布时间】:2018-09-24 16:10:30
【问题描述】:

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

我可以通过简单地刷新页面来解决问题,但是必须反复执行此操作很烦人,我想弄清楚问题可能是什么。如果我运行节点服务器而不是 nodemon,则不会发生这种情况。

这是我的客户端 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:

"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

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}`)
})

我正在使用 axios 处理我的前端 HTTP 请求:

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);

【问题讨论】:

    标签: reactjs econnrefused


    【解决方案1】:

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

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

    快递服务器 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 编译器,您可以使用/忽略)。

    ...
    "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)

    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导入所有文件):

    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);
    

    【讨论】:

    • 感谢您的回复!我今天在做服务器端护照的工作,主要使用 Postman,但我明天会回到客户端并尝试一下。
    • 谢谢!我从来没有使用过这个 cors 包。很漂亮。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-06-28
    • 1970-01-01
    • 2018-07-16
    • 2018-11-04
    • 1970-01-01
    • 2021-02-22
    • 2018-01-30
    相关资源
    最近更新 更多