首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >路由工作在本地,但不在Heroku上

路由工作在本地,但不在Heroku上
EN

Stack Overflow用户
提问于 2018-11-04 01:56:04
回答 1查看 2.5K关注 0票数 0

我开发了一个应用程序,它使用路由器文件feedback.router.js.。我已经设置了服务器来导入这个路由器文件,并将它用于'/feedback'请求。

我使用各种获取、发布、删除、放置路由与数据库进行通信。在本地,我的应用程序axios请求被正确地路由并与我的数据库集成。在我的server.js文件中,我阅读了其他问题,并实现了我认为express应该为生产版本服务的内容。当我在Heroku上运行应用程序时,我从任何axios请求中得到的响应似乎是HTML文件,该文件表明该路由未被识别,但我无法确定错误。我相信我为Heroku正确地设置了数据库,尽管问题可能就在那里。

这突出强调的一个间接问题是,一旦部署到Heroku上,我就不知道如何解决这些类型的请求。我已经将它连接到了我在Github上的存储库,并且找不到任何“服务器终端”来帮助搜索bug。任何关于如何使用Heroku进行故障排除的建议都是非常欢迎的。

更新包含GET和POST请求的Heroku日志:

2018-11-04T03:20:11.564616+00:00 2018-11-04T03:21:05.866976+00:00

我已经包括了我认为可能有用的文件。

文件结构(星号表示文件夹)

代码语言:javascript
复制
feedback-app
    **build**
    **public**
    **server**
        **modules**
             pool.js
        **routes**
             feedback.router.js
        server.js
    **src**
        **components**
             ...
        index.js
        registerServiceWorker.js
     data.sql
     package.json
     package-lock.json

我的axios请求的示例:

代码语言:javascript
复制
axios({
    method: 'GET',
    url: '/feedback'
}).then((response) => {
    console.log('response:',response);
    this.setState({
        display: 'all',
        feedback: response.data
    });
}).catch((error) => {
    console.log('error',error);
})

server.js

代码语言:javascript
复制
    const express = require('express');
    const app = express();
    const bodyParser = require('body-parser');
    const path = require('path');
    const PORT = process.env.PORT || 5000;
    const feedbackRouter = require('./routes/feedback.router');

    /** ---------- MIDDLEWARE ---------- **/
    app.use(bodyParser.json()); // needed for angular requests
    app.use(bodyParser.urlencoded({extended: true}));

    if (process.env.NODE_ENV === 'production') {
        // Exprees will serve up production assets
        app.use(express.static(path.join(__dirname, 'build')));

        // Express serve up index.html file if it doesn't recognize route
        app.get('*', (req, res) => {
          res.sendFile(path.join(__dirname, 'build', 'index.html'));
        });
    }

    /** ---------- EXPRESS ROUTES ---------- **/
    app.use('/feedback', feedbackRouter);

    /** ---------- START SERVER ---------- **/
    app.listen(PORT, () => {
        console.log('Listening on port: ', PORT);
    });

pool.js

代码语言:javascript
复制
const pg = require('pg');
const url = require('url');
let config = {};

if (process.env.DATABASE_URL) {
    // Heroku gives a url, not a connection object
    // https://github.com/brianc/node-pg-pool
    let params = url.parse(process.env.DATABASE_URL);
    let auth = params.auth.split(':');

    config = {
        user: auth[0],
        password: auth[1],
        host: params.hostname,
        port: params.port,
        database: params.pathname.split('/')[1],
        ssl: true, // heroku requires ssl to be true
        max: 10, // max number of clients in the pool
        idleTimeoutMillis: 30000, // how long a client is allowed to remain idle before being closed
    };

} else {
    // only change the things on the right side of the ||
    config = {
        user: process.env.PG_USER || null, //env var: PGUSER
        password: process.env.DATABASE_SECRET || null, //env var: PGPASSWORD
        host: process.env.DATABASE_SERVER || 'localhost', // Server hosting the postgres database
        port: process.env.DATABASE_PORT || 5432, //env var: PGPORT
        database: process.env.DATABASE_NAME || 'prime_feedback', //env var: PGDATABASE or the name of your database (e.g. database: process.env.DATABASE_NAME || 'koala_holla',)
        max: 10, // max number of clients in the pool
        idleTimeoutMillis: 30000, // how long a client is allowed to remain idle before being closed
    };
}

module.exports = new pg.Pool(config);

package.json

代码语言:javascript
复制
{
  "name": "react-reflection-board",
  "version": "0.1.0",
  "private": true,
  "proxy": "http://localhost:5000",
  "engines": {
    "npm": "6.4.1",
    "node": "10.11.0"
  },
  "dependencies": {
    "@material-ui/core": "^3.3.2",
    "@material-ui/icons": "^3.0.1",
    "axios": "^0.17.1",
    "bootstrap": "^4.1.3",
    "pg": "^7.4.1",
    "react": "^16.3.0",
    "react-confirm-alert": "^2.0.6",
    "react-dom": "^16.3.0",
    "react-progressbar": "^15.4.1",
    "react-redux": "^5.1.0",
    "react-router-dom": "^4.3.1",
    "react-scripts": "^2.1.1",
    "react-swal": "^3.0.0",
    "reactstrap": "^6.5.0",
    "recompose": "^0.30.0",
    "redux": "^4.0.1",
    "redux-logger": "^3.0.6",
    "serve": "^10.0.2"
  },
  "devDependencies": {
    "nodemon": "^1.18.5"
  },
  "scripts": {
    "dev": "react-scripts start",
    "start": "serve -s build",
    "build": "react-scripts build",
    "heroku-postbuild": "npm run build",
    "client": "react-scripts start",
    "server": "nodemon --watch server server/server.js",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject"
  },
  "browserslist": [
    ">0.2%",
    "not dead",
    "not ie <= 11",
    "not op_mini all"
  ]
}

feedback.router.js

代码语言:javascript
复制
    const express = require('express');
    const router = express.Router();
    const pool = require('../modules/pool');

    // GET feedback
    router.get('/', (req, res) => {
        // Request all entered feedback and return them
        pool.query('SELECT * FROM feedback ORDER BY id DESC;')
            .then((result) => {
                res.send(result.rows);
            }).catch((error) => {
                console.log('Error GET /api/feedback', error);
                res.sendStatus(500);  
        });
    })

    // GET feedback
    router.get('/flagged', (req, res) => {
        // Request all entered feedback and return them
        pool.query('SELECT * FROM feedback WHERE flagged = true ORDER BY id DESC;')
            .then((result) => {
                res.send(result.rows);
            }).catch((error) => {
                console.log('Error GET /api/feedback/flagged', error);
                res.sendStatus(500);  
        });
    })

    // POST new feedback entry
    router.post('/', async (req, res) => {
        const client = await pool.connect();

        try {
            const {
                feeling,
                understanding,
                support,
                comments,
                flagged
            } = req.body;
            await client.query('BEGIN')
            const orderInsertResults = await client.query(`INSERT INTO feedback ("feeling","understanding","support","comments","flagged")
            VALUES ($1, $2, $3, $4, $5);`, [feeling, understanding, support, comments, flagged]);

            await client.query('COMMIT')
            res.sendStatus(201);
        } catch (error) {
            await client.query('ROLLBACK')
            console.log('Error post /api/feedback', error);
            res.sendStatus(500);
        } finally {
            client.release()
        }
    });

    // DELETE a feedback entry
    router.delete('/:id', (req, res) => {
        pool.query('DELETE FROM feedback WHERE id=$1', [req.params.id]).then((result) => {
            res.sendStatus(200);
        }).catch((error) => {
            console.log('Error delete /api/feedback', error);
            res.sendStatus(500);
        })
    });

    // PUT / update a feedback entry
    router.put('/:id', (req,res) => {
        let feedbackId = req.params.id;
        let updatedFlagStatus = req.body.updatedFlagStatus;
        console.log('to update flag of item',feedbackId,'to',updatedFlagStatus);
        const sqlText = `UPDATE feedback SET flagged = $2 WHERE id=$1`;
        console.log('sqlText:',sqlText);
        pool.query(sqlText,[feedbackId, updatedFlagStatus])
            .then( (result) => {
                console.log('successfully updated flag status', result);
                res.sendStatus(200);
            })
            .catch( (error) => {
                console.log('error updating flag status', error);
                res.sendStatus(500);
            })
    })

    module.exports = router;
EN

回答 1

Stack Overflow用户

发布于 2018-11-04 02:55:56

每当您使用Express来提供React + ReactRouter应用程序时,您都会遇到这样的情况,即Express路由和routing路由器“冲突”。

在生产环境中,您的快速服务器将“如果不识别路由就提供index.html文件”,所以当您请求/feedback时,第一个匹配的是行app.get('*'...,这就是为什么Ajax请求实际上返回index.html文件的原因。

代码语言:javascript
复制
if (process.env.NODE_ENV === 'production') {
    // Exprees will serve up production assets
    app.use(express.static(path.join(__dirname, 'build')));

    // Express serve up index.html file if it doesn't recognize route
    app.get('*', (req, res) => {
      res.sendFile(path.join(__dirname, 'build', 'index.html'));
    });
}

/** ---------- EXPRESS ROUTES ---------- **/
app.use('/feedback', feedbackRouter);

将您的app.use('/feedback', feedbackRouter);行放在最开始的位置,它应该可以工作。

现在,您应该完全安装"Heroku工具箱“https://devcenter.heroku.com/articles/heroku-cli,以便在您的终端上运行heroku logs -t以便能够调试您的服务器端代码。

希望能帮上忙!

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53137113

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档