Маршрутизация с помощью Express API и ReactJS SPA - PullRequest
1 голос
/ 24 октября 2019

Я недавно развернул сайт, используя React на Heroku. В консоли браузера я получил вывод html-текста, а не моего javascript пользовательского интерфейса.

Ссылка на мой сайт Ссылка на хранилище

Я думаю, что проблема коренится в моем маршруте server.js для обслуживания моего index.html

server.js

// Allows us to place keys and sensitive info in hidden .env file
require("dotenv").config();

// Require Packages
const express = require("express");
const app = express();
const morgan = require("morgan")
const db = require("./models");
const routes = require("./routes");
const passport = require("passport");
const session = require("express-session")
const path = require("path");

const MySQLStore = require("express-mysql-session")(session);

require("./config/passport")(passport)
app.use(express.urlencoded({ extended: true }));
app.use(express.json());

let options = {};
if (process.env.NODE_ENV === 'production') {
    options = {
        host: process.env.HOST,
        port: 3306,
        user: process.env.USER,
        password: process.env.PASSWORD,
        database: process.env.DB
    }
} else {
    options = {
        host: 'localhost',
        port: 3306,
        user: 'root',
        password: process.env.DB_PASSWORD,
        database: 'tracker'
    }
}


// Options for mysql session store

let sessionStore = new MySQLStore(options);

// Pass in mysql session store
app.use(session({
    key: 'surfing_dogs',
    secret: 'surfing_dogs',
    store: sessionStore,
    resave: false,
    saveUninitialized: false
}))

app.use(passport.initialize());
app.use(passport.session());

app.use(morgan('common'))


// THIS IS REALLY IMPORTANT FOR ROUTING CLIENT SIDE
// We want to have our app to use the build directory 
app.use(express.static(__dirname + '/client/build'))

// For every url request we send our index.html file to the route
app.get("/*", (req, res) => {
    res.sendFile(path.join(__dirname, "client", "build", "index.html"));
});

app.use(routes)


db.sequelize.sync({ force: false }).then(() => {
    let server = app.listen(process.env.PORT || 5000, function () {
        let port = server.address().port;
        console.log(`Server is listening on PORT ${port}`)
    })
})

Чтобы уточнить, я разместил этот маршрут в моем server.jsпотому что у меня есть клиентская маршрутизация, и я хочу заставить браузер всегда обслуживать index.html

Еще одна причина, по которой я хочу решить эту проблему, заключается в том, что в настоящее время я не могу войти на свой сайт с использованием учетных данных.

Вот небольшая часть процесса входа в систему. Моя цель была основана на состоянии входа в систему, но, к сожалению, состояние входа в систему не меняется.

 if (this.state.loggedIn === true) {
      return (
        <Router>
          <Navbar user={this.state.user} logout={this.logout} />
          <Switch>
            {this.state.userType === 'administrator' ? <Route path='/' exact component={() => <AdminHome user={this.state.user} />} /> : ''}
            {this.state.userType === 'instructor' ? <Route path='/' exact component={() => <InstructorHome user={this.state.user} />} /> : ''}

            {/* Path for student profile based on it */}
            <Route exact path='/student/:id' exact component={StudentProfile} />

            {this.state.userType === 'student' ? <Route path='/' exact component={() => <StudentHome user={this.state.user} />} /> : ''}
            <Route exact path='/settings' exact component={() => <Settings user={this.state.user} />} />
            <Route component={NoPage} />
          </Switch>
        </Router>
      )
    } else {
      return (
        <Router>
          <Switch>
            <Route path='/' exact component={SplashPage} />
            <Route path='/login' exact component={Login} />
            <Route path='/signup' exact component={Signup} />

            {/* Go to signup based on cohortID */}
            <Route path='/signup/:id' exact component={CohortSignup} />

            <Route component={NoPage} />

          </Switch>
        </Router>
      )
    }

Надеюсь, кто-нибудь может мне помочь!

1 Ответ

1 голос
/ 24 октября 2019

Посмотрев репозиторий на server.js, вы отправляете весь ваш трафик, который попадает на ваш сервер (даже ваши собственные запросы API) на ваш интерфейс.

Сначала убедитесь, что ваши серверные маршруты начинаются счто-то различимое, такое как

app.get('/api/*',(req,res)=>/*somecode*/)

Это потому, что ваш сервер будет путать что-то вроде '/ login', если это также маршрут в вашем внешнем интерфейсе, и он будет обслуживать только один или другой в зависимости от того, когда ониопределены.

Затем обновите ваш server.js, чтобы он соответствовал этому, и он должен работать:

//API Requests handled first
require('./routes')(app);

//Non api requests in production
if (process.env.NODE_ENV === 'production') {
    app.use([someProductionMiddleware()])
    // Express will serve up production assets i.e. main.js
    app.use(express.static('client/build'));
    // If Express doesn't recognize route serve index.html
    const path = require('path');
    app.get('*', (req, res) => {
        res.sendFile(
            path.resolve(__dirname, 'client', 'build', 'index.html')
        );
    });
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...