Я унаследовал фреймворк для статического веб-сайта, который использует react и react-router-dom для Routes. Мы хотим, чтобы веб-сайт мог поддерживать динамическую загрузку контента на страницы через идентификатор.
Например, у меня есть страница /articles, на которой перечислены все статьи, и когда вы нажимаете на одну из перечисленных статей, открывается URL-адрес /articles/ABCDEFG, а затем загружается компонент страницы статьи и извлекаются данные для этого конкретного идентификатора. Это полностью работает на локальном разработчике, однако после развертывания в рабочей среде (размещенной как приложение веб-сайта Azure) все страницы работают, кроме тех, которые имеют динамический URL-адрес.
Я новичок в реагировании, но из того, что я читал, сайты со статической реакцией не могут использовать /: id, потому что для этого требуется, чтобы каждая страница уже существовала.
Я выполнил поиск и попытался удалить все, что связано со статикой, с сервера и веб-конфигурации.
var express = require('express');
var serveStatic = require('serve-static');
var fallback = require('express-history-api-fallback');
var app = express();
var publicDir = path.resolve(__dirname, '../www');
// app.use('/', serveStatic(publicDir));
//app.use(fallback('index.html', { root: publicDir }));
app.listen(process.env.PORT);
Мои маршруты настроены так
generateRoutes() {
return (
<Switch>
<Route exact path = "/" component = {Home} />
<Route exact path = "/about" component = {About} />
<Route exact path = "/articles" component = {Articles} />
<Route path = "/articles/:id" component = {Article} />
<Route exact path = "/careers" component = {Careers} />
<Route exact path = "/people" component = {People} />
<Route path = "/profile/:id" component = {Profile} />
</Switch>
);
}
Я хочу, чтобы когда я помещал URL-адрес в адресную строку, например https://example.com/site/profile/246b9e73-5332-4afb-92b8-be5a061bd908, он отображал страницу профиля с этим идентификатором.
Вместо этого я получаю 404 сообщение о том, что страница не может быть найдена. Я не уверен, гоняюсь ли я за кроличьей норой со статической/динамической идеей, но я потратил около 2 дней, пытаясь понять, почему это до сих пор не работает, и я готов попробовать что угодно.
ваш экспресс-сервер должен отображать приложение (index.html) на всех маршрутах (или в комплексе *), иначе вы не запустите JS / react-router
@JohnRuddell: не обязательно, если используется express-history-api-fallback, что в основном делает то же самое.
конечно, если запасной вариант не закомментирован :)
Также вы говорите, что ваш URL-адрес /site/profile/246b... Но ваш маршрутизатор настроен только на /profile/:id
Я закомментировал эти строки, чтобы посмотреть, не сделает ли это их статичными. Насколько я могу судить из чтения руководств, /:id означает, что это будет параметр, а не фактическая страница, и когда маршрут /profile/:id (или в примере /site/profile/246...) replaces делает это значение для компонента в качестве идентификатора параметра. Единственная разница, которую я увидел, заключалась в том, что вместо резервного нажатия на index.html, если страница 404 отображала бы 404
Да, я просто упомянул, что у вас есть дополнительный каталог «/site/» в URL-адресе, но не на вашем маршруте.
О, да. Это потому, что все находится внутри папки с именем /site/
Кроме того, я попробовал /profile/* вместо profile/:id, и он все равно дал мне 404, но опять же только на производстве. Localhost работает как положено. Должен ли я создать папку внутри /profile с именем * с index.html, чтобы она работала?





Раздел развертывание в приложении create-react-app уже рассмотрел эту проблему, заявив
If you use routers that use the HTML5 pushState history API under the hood (for example, React Router with browserHistory), many static file servers will fail. For example, if you used React Router with a route for /todos/42, the development server will respond to localhost:3000/todos/42 properly, but an Express serving a production build as above will not.
This is because when there is a fresh page load for a /todos/42, the server looks for the file build/todos/42 and does not find it. The server needs to be configured to respond to a request to /todos/42 by serving index.html. For example, we can amend our Express example above to serve index.html for any unknown paths:
Итак, решение для вас состоит в том, чтобы изменить
app.use('/', serveStatic(publicDir));
к
app.use('/*', serveStatic(publicDir));
Надеюсь это поможет
Я попытался следовать связанной документации, и это именно та проблема, которую я пытаюсь решить, однако это не сработало. var path = require('path'); var express = require('express'); const app = express(); app.use(express.static(path.join(__dirname, '../www'))); app.get('/*', function (req, res) { res.sendFile(path.join(__dirname, '../www', 'index.html')); }); app.listen(process.env.PORT); Я также пытался изменить маршруты с /:id на /*, но это тоже не сработало,
Я полагаю, что это как-то связано с ../www, этот скрипт работает в родственном каталоге www? Также вы можете подтвердить, что express server работает и обслуживает файлы?
Поэтому я провел еще одно расследование. Оказывается, этот серверный файл на самом деле не используется. Это было в фреймворке, поэтому, когда я сделал это, не было никаких изменений.
@Джон, ты мог пропустить настройку web.config ??? Это может помочь medium.com/@to_pe/…
ИДЕАЛЬНО!! Большое спасибо. Это именно то, что мне нужно, чтобы эти маршруты работали. С настройкой web.config, которая обрабатывает мои маршруты, поэтому мне не нужно добавлять сервер, если позже мы не решим перейти к SSR.
Я уверен, что закомментированные строки в вашем фрагменте кода были опечаткой. Если нет, раскомментируйте их и попробуйте проверить, работает ли это.