React Router способен выполнять маршрутизацию только при запуске с корневого url-адреса



У меня есть приложение React, которое также использует Redux и ReactRouter.



Моя проблема заключается в следующем:



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



Однако, если я наберу в навигационной панели любой url, отличный от корневого, я получу странную ошибку:
Введите описание изображения здесь
Введите описание изображения здесь



Я действительно не понимаю, как можно получить такую ошибку.

Если я пойду для localhost:1337/, а затем нажмите на элемент со ссылкой /cars/1, все будет хорошо, и компонент будет успешно отрисован. Если я наберу localhost:1337/cars/1 сразу (или любой другой существующий маршрут), я получу эту ошибку.



Вот как я инициализирую react-маршрутизатор и определяю свои маршруты:



Индекс.js:



require('./style/style.css');

import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware } from 'redux';
import { Router, browserHistory } from 'react-router';
import reduxPromise from 'redux-promise';

import routes from './routes';
import reducers from './reducers';


const createStoreWithMiddleware = applyMiddleware(
reduxPromise
)(createStore);

ReactDOM.render(
<Provider store={createStoreWithMiddleware(reducers)}>
<Router history={browserHistory} routes={routes} />
</Provider>
, document.querySelector('.container.app')
);


Маршруты.js:



import React from 'react';
import { Route, IndexRoute, Redirect } from 'react-router';

import App from './components/app';
import CarsIndex from './containers/cars-index';
import CarNew from './containers/car-new';
import CarShow from './containers/car-show';
import CarEdit from './containers/car-edit';
import SignIn from './containers/signin';
import auth from './auth/auth';


function requireAuth(nextState, replace) {
if (!auth.loggedIn()) {
replace({
pathname: '/authenticate',
state: { nextPathname: nextState.location.pathname }
});
}
}

function filterLoggedIn(nextState, replace) {
if (auth.loggedIn()) {
replace({
pathname: '/',
state: { nextPathname: nextState.location.pathname }
});
}
}

export default (
<Route path='/' component={App}>
<IndexRoute component={CarsIndex} onEnter={requireAuth} />
<Route path='cars/new' component={CarNew} onEnter={requireAuth} />
<Route path='cars/:id' component={CarShow} onEnter={requireAuth} />
<Route path='cars/edit/:id' component={CarEdit} onEnter={requireAuth} />
<Route path='authenticate' component={SignIn} onEnter={filterLoggedIn} />
<Redirect from='*' to='/' />
</Route>
);


Мой сервер-это маленький экспресс.JS приложение и перенаправляет любые запросы, кроме /api/* на страницу index.html.



Вот часть из мой server.js:



const path = require('path');
const port = process.env.PORT || 1337;
const app = express();
const pathToStatic = path.join(__dirname, 'static');
express.static(path.join(__dirname, 'static'));
app.use(express.static(pathToStatic));
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(bodyParser.json());
app.get('/api/cars', (req, res) => {
return Car.find((err, cars) => {
if (!err) {
return res.send(cars);
} else {
console.log(err);
res.statusCode = 500;
return res.send({ error: 'Server error' });
}
});
});
app.get('*', (req, res) => {
res.sendFile(path.resolve(pathToStatic, 'index.html'));
});

app.listen(port, () => {
console.log(`Express server is listening on port ${port}`);
});




Сталкивались ли вы с такой проблемой? Не могли бы вы помочь мне найти ответ на этот вопрос?

639   1  

1 ответ:

Скриншот показывает, что bundle.js (при запросе) возвращает index.html.

Это потому, что ваши экспресс-маршруты обрабатывают маршрут api/cars, а затем по умолчанию все остальное индексировать.формат html.

Конечно, все ваши ресурсы, которые появляются на index.html, также должны быть отправлены браузеру. Это включает в себя <script src="bundle.js"></script>, который браузер запросит, как только он получит index.html в первый раз.

Итак, у вас должен быть какой-то способ разрешить express обрабатывать запросы на ресурсы, которые index.html потребности.

Популярным решением для этого являетсямонтирование каталога активов и размещение его над маршрутом по умолчанию. Что-то вроде:

// api routes

app.use(express.static('assets'));

// default route

Затем убедитесь, что ваш bundle.js находится в каталоге активов. И затем, что тег сценария выглядит как <script src="/assets/bundle.js"></script>.

Comments

    Ничего не найдено.