apache 在本地工作但不用于生产的快速路线

yvgpqqbh  于 12个月前  发布在  Apache
关注(0)|答案(1)|浏览(84)

我们目前正在部署一个静态的react应用程序,由nodejs / express服务器通过apache 2反向代理提供服务。应用程序索引工作正常,但我试图重定向,如果一个页面不存在,这是工作在本地主机,但不是在远程服务器上。如果我转到myip/foo,我将收到cannot GET /foo
下面是我的server.js:

const express = require("express");
const app = express();
const port = 8080;
const bodyParser = require("body-parser");
const cors = require("cors");
const db = require("./src/models/db.models");
const compression = require("compression");
app.use(bodyParser.json());
app.use(cors());
//Disable x-powered-by header for security reason
app.disable("x-powered-by");
// use compression (gzip etc) for each request to increase perf
app.use(compression());
app.get("/login", (req, res) => {
  res.sendFile(__dirname + "/client/index.html");
});
app.get("/signUp/:id", (req, res) => {
  res.sendFile(__dirname + "/client/index.html");
});
// force: true will drop the table if it already exists (so drop all the data too)
db.sequelize
  .sync()
  .then(() => {
    console.log("Server Running ‍(*-*)");
  })
  .catch((err) => console.log("Error ¯_(ツ)_/¯", err));
require("./src/routes/user.routes")(app);
require("./src/routes/auth.routes")(app);
require("./src/routes/pageContents.routes")(app);
require("./src/routes/survey.routes")(app);
require("./src/routes/theme.routes")(app);
require("./src/routes/question.routes")(app);
require("./src/routes/surveyQuestion.routes")(app);
require("./src/routes/surveyHasUser.routes")(app);
require("./src/routes/answer.routes")(app);
require("./src/routes/surveyHasTheme.routes")(app);
// use static folder to render builded front react app
app.use(express.static("client"));
app.listen(port, () => console.log(`Listening on port ${port}`));

这是我的app.js(前端),在后端文件夹中构建和设置

import './App.css';
import Login from './pages/login/Login.page';
import React from 'react';
import { BrowserRouter, Route, Redirect } from 'react-router-dom';
import Intro from './pages/questionnaire/Intro/Intro.page';
import Edito from './pages/edito/Edito.page';
import Cgu from './pages/cgu/Cgu.page';
import { Switch } from 'react-router-dom';
import Questionnaire from './pages/questionnaire/Questionnaire/Questionnaire.page';
import Remerciement from './pages/questionnaire/Remerciement/Remerciement.page';
import ListeQuestionnaire from './pages/liste/ListeQuestionnaire.page';
import ProtectedRoute from './components/utils/ProtectedRoute.component';
import AuthService from '../src/services/auth.service';
import LogOut from './components/utils/logOut.component';
import TableauDeBord from './pages/tableauDeBord/tableauDeBord.page';
import SignUp from '../src/pages/signUp/signUp.page';
function App() {
    return (
        <div className="App">
            <BrowserRouter>
                <Switch>
                    <ProtectedRoute path="/intro" component={Intro} />
                    <Route path="/signUp/:token" component={SignUp} />
                    <Route path="/login" component={() => (AuthService.isAuthenticated() ? <Redirect to="/" /> : <Login />)} />
                    <ProtectedRoute path="/questionnaire" component={Questionnaire} />
                    <ProtectedRoute path="/remerciement" component={Remerciement} />
                    <ProtectedRoute path="/listeQuestionnaire" component={ListeQuestionnaire} />
                    <ProtectedRoute path="/cgu" component={Cgu} />
                    <ProtectedRoute path="/logOut" component={LogOut} />
                    <ProtectedRoute path="/edito" component={Edito} />
                    <Route path="/:token" component={SignUp} />
                    <ProtectedRoute path="/" component={TableauDeBord} />
                </Switch>
            </BrowserRouter>
        </div>
    );
}
export default App;

最后是我的Apache配置文件:

<VirtualHost *:80>
#    ServerName domain.com
#    ServerAlias www.domain.com
    DocumentRoot "/www/html/360-nodejs"
    ProxyRequests Off
    ProxyPreserveHost On
    ProxyVia Full
    AllowEncodedSlashes On
    ErrorLog "/var/log/apache2error.log"
    CustomLog "/var/log/apache2errorcustom.log" common

    <Proxy *>
            #Require all granted
     Order deny,allow
     Allow from all
    </Proxy>

    ProxyPass / http://127.0.0.1:8080/
    ProxyPassReverse / http://127.0.0.1:8080/
</VirtualHost>

Apache日志显示,当我们调用/:id/signUp/:id时会关闭,但服务器仍在运行
我可以直接链接到另一个路由,但是如果我刷新页面,我会得到一个404,如果我在URL中写入它,它不再工作,404,所以我不能查询像/:id这样的直接URL,因为我也会得到一个404

qncylg1j

qncylg1j1#

像往常一样,我应该更好的RTFD。https://create-react-app.dev/docs/deployment/#serving-apps-with-client-side-routing
如果你使用的路由器在底层使用了HTML5 pushState历史API(例如,React Router with browserHistory),那么很多静态文件服务器都会失败。例如,如果您使用React Router,路由为/todos/42,开发服务器将正确响应localhost:3000/todos/42,但如上所述的Express服务于生产构建不会。
这是因为当有一个/todos/42的新页面加载时,服务器会查找文件build/todos/42,但没有找到它。服务器需要配置为通过提供index.html来响应对/todos/42的请求。例如,我们可以修改上面的Express示例,为任何未知路径提供index.html:

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

如果您使用的是Apache HTTP Server,则需要在public文件夹中创建一个.htaccess文件,如下所示:

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

当你运行npm run build时,它会被复制到build文件夹。
我修改了我的server.js并添加了.htaccess,事情解决了。

相关问题