从dev env将React应用程序部署到Heroku后,Fetch请求中断 - 所有GET请求返回索引.html -



我刚刚将我的Create-React-App项目部署到Heroku。在开发中,我运行两个单独的端口 - 本地 HTML + JS 使用 ReactWebpackDevServer使用 Port 3000 上的npm/yarn start脚本提供服务。后端是在端口 3001 上运行的 Express + NodeJS。我将所有获取请求配置为使用mode:'cors'并在 API 上提供了一个处理程序,以避免 CORS 错误。 典型的抓取请求如下所示:

当我部署到 Heroku 时,现在所有内容都保存在一个 Dyno 上,Express 应用程序提供 React 文件(捆绑 + 索引.html(,并处理后端路由逻辑。

以下是到目前为止我的 API 代码示例:

const express = require('express');
const mongoose = require('mongoose');
const path = require('path');
const bodyParser = require('body-parser');
const config = require('./models/config');
require('dotenv').config()
const app = express();
const server = require('http').createServer(app);
const storeItems= require('./controllers/storeItems')
const authorize= require('./controllers/authorize')
const router = express.Router(); 
mongoose.Promise = global.Promise; 
mongoose.connect(`mongodb://${process.env.MLABS_USER}:${process.env.MLABS_PW}@ds113000.mlab.com:13000/omninova`, { useMongoClient: true });
app.use(bodyParser.json());
// Middleware to handle CORS in development:
app.use('/*', function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, x-access-token, x-user-pathway, x-mongo-key, X-Requested-With, Content-Type, Accept");
res.header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT");
next();
});
app.use(express.static(path.join(__dirname, 'client/build')));
router.route('/api/storeItem/')
.get(storeItems.getAllStoreItems)
.post(storeItems.createNewStoreItem);
router.route('/authorize')
.post(authorize.login);
// Catch-All Handler should send Client index.html for any request that does not match previous routes
router.route('*')
.get((req, res) => {
res.sendFile(path.join(__dirname+'/client/build/index.html'));
});
app.use('/', router);
server.listen(config.port);
module.exports = app;

我遇到了一些问题,我所有的 get 请求都返回我的索引.html页面,并显示以下错误:Unexpected token < in JSON at position 0

我有以下获取请求:

return fetch(`/api/storeItem`, {
headers:{
'Content-Type': 'application/json',
},
method: 'GET',
mode: 'no-cors',
})
.then(response => response.ok ? response.json() : Promise.reject(response))
.then(json => {
dispatch(receiveItems(json))
})
.catch(err => console.log(err))

这是失败的,因为它不是触发应该在后端storeItems.getAllStoreItems运行的快速中间件,而是在初始请求时传递该路由并触发我用来提供索引的 catch-all 处理程序.html:

router.route('*')
.get((req, res) => {
res.sendFile(path.join(__dirname+'/client/build/index.html'));
});

另一个混淆是,以下获取请求返回 404,即使/authorize路由在 API 代码中期待 POST 请求:

export function attemptLogIn(credentials) {
return dispatch => {
return fetch('/authorize', {
headers:{
'Content-Type': 'application/json'
},
method: 'POST',
mode: 'no-cors'
body: JSON.stringify(credentials)
})
.then(response => response.ok ? response.json() : Promise.reject(response.statusText))
.then(json => {
dispatch(routeUserAfterLogin(json.accountType))
})
.catch(err => dispatch(authFail(err.message)))
}
} 

任何这方面的帮助将不胜感激。我假设我对高速路由器做了什么错误,因为授权路由只是没有被拾取。

我按照这篇博文中的说明帮助我设置了新项目:https://daveceddia.com/deploy-react-express-app-heroku/

编辑:这是从我的开发分支获取代码。这将成功登录用户,而不返回 404。但是,我根本不使用 catch-all 处理程序或 express.static 中间件:

return fetch('http://localhost:3001/authorize', {
headers:{
'Content-Type': 'application/json'
},
method: 'POST',
mode: 'cors', 
body: JSON.stringify(credentials)
})

编辑:我刚刚更改了指向捆绑包的 URL.js 到app.use(express.static(path.join(__dirname, '/../../build')));我不确定我之前是如何发送 HTML 的,因为那是构建文件的实际位置。我不确定他们以前是如何被发现的。

Edit2:找到了我的问题,我留在了我的 React 项目的启动脚本中(它实际上启动了 webpack 开发服务器......

对于第一部分

错误:JSON 中位置 0 处出现意外的令牌<</p>

我的猜测是,如果没有开发服务器,Express 无法自动处理捆绑包下载。因此,当你的索引.html命中/path/to/bundle.js时,它属于通配符 ("*"( 路由,该路由返回 HTML 本身。然后,您的浏览器尝试将其解析为 JS,但它不能,因为它是 HTML,因此会出现错误。

我会尝试这样的事情:

app.get("path/to/bundle.js", (req, res) => {
res.sendFile("path/to/bundle.js");
});

您的服务器没有发送 json 响应,而是发送 HTML 内容。将响应更改为 res.text(( 并记录它。 https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch

router.route('*')
.get((req, res) => {
res.sendFile(path.join(__dirname+'/client/build/index.html'));
});

这应该可以解决问题。代替"*"应该是"/"。现在我的GET请求就像Heroku上的POST一样工作。

https://stackoverflow.com/a/37878281/12839684

最新更新