Plesk/React/Express - 起点是(React)索引.html。但是我无法执行后端请求



自从我做了更多研究以来的大编辑

我正在尝试使用Plesk在云服务器上部署我的第一个Nodejs/Rect应用程序。

这是我首先尝试的:我创建了一个包含以下内容的.httaccess文件。

Options -MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.html [QSA,L]

问题是,我再也无法访问express app.js了,因为react的index.html文件可以处理所有内容。因此,另一种选择是从express相应地路由出app.js。我已经找到了以下方法并尝试实现它

近似:

/api/app.js
app.use('/result', resultRouter);
app.use(express.static(path.join(__dirname, 'build')));
app.get('/', function (req, res) {
res.sendFile(path.join(__dirname, 'build', 'index.html'));
});
app.get('/*', function (req, res) {
res.sendFile(path.join(__dirname, 'build', 'index.html'));
});

我的实现:

var createError = require('http-errors');
var express = require('express');
const cors = require('cors');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
require('dotenv').config();
var helmet = require('helmet');
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var resultRouter = require('./routes/result');
var app = express();
app.use(helmet());
app.use(cors());
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', 'http://localhost:3000');
next();
});
//Set up mongoose connection
var mongoose = require('mongoose');
var mongoDB = 'MYMONGODBURL';
mongoose.connect(mongoDB, { useNewUrlParser: true, useUnifiedTopology: true });
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'MongoDB connection error:'));
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use('/result', resultRouter);
app.use(express.static(path.join(__dirname, 'build')));
app.get('/', function (req, res) {
res.sendFile(path.resolve(__dirname, 'build', 'index.html'));
});
app.get('*', function (req, res) {
res.sendFile(path.resolve(__dirname, 'build', 'index.html'));
});
// catch 404 and forward to error handler
app.use(function (req, res, next) {
next(createError(404));
});
// error handler
app.use(function (err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;

虽然我确信这是一个正确的解决方案,但我没有实现它。app.js文件位于api文件夹中。在上传到Plesk之前,我从react内部插入了构建文件夹。因此app.jsbuild文件夹位于目录的同一级别。

通过git上传后,我将文档根和应用程序根都设置为configurationr/api。Configurator只是我事先设置的一个空文件夹。

如果我将文档根设置为configurationr/api/build,则会显示我的react index.html文件的起始页。但是路由到任何其他react组件都不起作用。

我做错了什么?我还启用了";浏览域";,但是仍然得到504网关超时错误。

我希望有人能给我指明正确的方向,或者对我下一步应该去哪里有一些意见。

提前感谢

找到了我的问题的解决方案

所以我知道我的问题还处于初级阶段,事后看来,我没有提供足够的信息让别人来帮助我。但我找到了一个解决方案,希望能帮助其他陷入困境的初学者。因此,我写信分享我在这个过程中学到的东西,并对其进行反思

2种在Plesk上快速反应的方法

基本上有两种方法可以在Plesk上运行react/express。这两种解决方案都是可行的,但解决了不同的先决条件。

解决方案1:您希望通过react呈现一个静态站点,该站点不执行任何对nodejs的后端请求。

在这种情况下,您可以在react文件夹中运行ǹpm run build,并将新创建的构建文件夹放入express文件夹中。在构建文件夹中,创建一个.htaccess文件,其中包含以下内容:

Options -MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.html [QSA,L]

我认为这样做,你甚至不需要nodejs。但我还没有试过。无论如何通过git将文件夹(我们称之为api(上传到Plesk,并将文档根设置为api/build,而应用程序根只是api。

解决方案2:您希望呈现静态react,但您执行后端请求以在任何时候表达某些业务逻辑或数据库请求。

与解决方案1一样,创建构建文件夹并将其移动到api文件夹中。构建文件夹是React为应用程序最终工作所需的一切。在api文件夹中,在根级别上创建一个新的Javascript文件。将其命名为server.js。在里面放入以下代码:

const app = require('./app');
const http = require('http');
http.createServer(app).listen(process.env.PORT);

据我所知,这首先会启动您的服务器,如果没有,您将收到504超时错误。

第二,您需要告诉nodejs,无论何时您到达一个未在express中定义的路由,它都会重定向到react的index.html文件。为此,请打开你的app.js文件。在最后一条快递路线的正下方插入以下内容:

app.use('/result', resultRouter); 
// ^ above is the last route of my express app. 
// below tells your server to redirect all other routes to index.html from React
app.use(express.static(path.join(__dirname, 'build')));
app.get('/', function (req, res) {
res.sendFile(path.resolve(__dirname, 'build', 'index.html'));
});
app.get('*', function (req, res) {
res.sendFile(path.resolve(__dirname, 'build', 'index.html'));
});

在修改并上传到Plesk后,将您的文档根和应用程序根从Plesk Nodejs应用程序设置为api(或任何根文件夹(。然后,将应用程序启动文件设置为server.js。现在一切都应该正常了。

故障排除

以下是我在路上遇到的一些障碍,你也可能面临。

  • 内容安全策略错误:使用解决方案2成功设置所有内容后,我收到了一个内容安全策略出错。这是因为我在express应用程序中使用了中间件Helmet。评论头盔,以测试是否有问题。如果是,有一些方法可以正确设置头盔。你真的不需要禁用它
  • CORS错误:我的后端请求失败,同源策略受到损害。这是因为从react到express的axios请求仍然指向localhost。将React中的所有axios请求url替换为生产域中的正确url

最新更新