我开发了一个使用路由器文件 feedback.router.js 的应用。我已将服务器设置为导入此路由器文件,并将其用于'/feedback'
请求。
我使用各种GET,POST,DELETE,PUT路由与数据库进行通信。在本地,我的应用程序axios请求已正确路由,并与我的数据库正确集成。在我的server.js文件中,我阅读了其他问题,并实现了我认为express应该用于生产版本的内容。当我在Heroku上运行该应用程序时,我从任何axios请求中收到的响应似乎都是HTML文件,该文件指示无法识别该路由,但是我无法确定该错误。我相信我为Heroku正确设置了数据库,尽管问题可能出在这里。
一个突出的间接问题是我不知道一旦部署在Heroku上后如何解决这些类型的请求。我已经将它与我在Github上的存储库连接了,但是找不到任何“服务器终端”来协助错误查找。非常欢迎提供任何有关如何使用Heroku解决此问题的建议。
更新以包含GET和POST请求的Heroku日志:
2018-11-04T03:20:11.564616 + 00:00 heroku [router]:at = info method = POST path =“ / feedback” host = prime-feedback-app.herokuapp.com request_id = 65732134-d050-4f82-ab08-9d0764266cb3 fwd =“ 73.242.14.56” dyno = web.1 connect = 0ms服务= 3ms status = 200字节= 2377 protocol = https
2018-11-04T03:21:05.866976 + 00:00 heroku [router]: at = info method = GET path =“ / feedback” host = prime-feedback-app.herokuapp.com request_id = 6b1b7341-5dbf-443d-bff4-e0a6e3080e51 fwd =“ 73.242.14.56” dyno = web.1 connect = 0ms服务= 3ms status = 200字节= 2377 协议= https
我提供了我认为可能有用的文件。
文件结构(星号表示文件夹)
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请求示例:
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
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
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
{
"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
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;
答案 0 :(得分:1)
每当您使用Express来服务React + ReactRouter应用时,都会遇到Express路由和React Router“冲突”的情况。
在生产环境中,您的Express服务器将“如果无法识别路由,则提供index.html文件” ,因此,当您请求/feedback
时,第一行是app.get('*'...
,这就是您的Ajax请求实际上返回index.html文件的原因。
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 Toolbelt” https://devcenter.heroku.com/articles/heroku-cli,以便可以在终端上运行heroku logs -t
以便调试服务器端代码。
希望有帮助!