Recuerda que en la informática cualquier problema casi siempre tiene más de una soluciones, no obstante aquí compartimos lo más óptimo y eficiente.
Solución:
Al observar los comentarios sobre la respuesta aceptada y la naturaleza genérica de esta pregunta (‘no funciona’), pensé que este podría ser un buen lugar para algunas explicaciones generales sobre los problemas involucrados aquí. Entonces, esta respuesta está pensada como información de fondo / elaboración sobre el caso de uso específico del OP. Por favor, tenga paciencia conmigo.
Del lado del servidor vs del lado del cliente
Lo primero que hay que entender sobre esto es que ahora hay 2 lugares donde se interpreta la URL, mientras que solía haber solo 1 en ‘los viejos tiempos’. En el pasado, cuando la vida era simple, algún usuario enviaba una solicitud de http://example.com/about
al servidor, que inspeccionó la parte de la ruta de la URL, determinó que el usuario estaba solicitando la página acerca de y luego devolvió esa página.
Con el enrutamiento del lado del cliente, que es lo que proporciona React-Router, las cosas son menos simples. Al principio, el cliente aún no tiene ningún código JS cargado. Entonces, la primera solicitud siempre será al servidor. Eso luego devolverá una página que contiene las etiquetas de script necesarias para cargar React y React Router, etc. Solo cuando esos scripts se han cargado, comienza la fase 2. En la fase 2, cuando el usuario hace clic en el enlace de navegación “Acerca de nosotros”, por ejemplo, se cambia la URL. solo localmente para http://example.com/about
(hecho posible por la API de historial), pero no se realiza ninguna solicitud al servidor. En cambio, React Router hace lo suyo en el lado del cliente, determina qué vista de React renderizar y la renderiza. Suponiendo que su página acerca de no necesita hacer ninguna llamada REST, ya está hecho. Ha realizado la transición de Inicio a Acerca de nosotros sin que se haya disparado ninguna solicitud del servidor.
Básicamente, cuando haces clic en un enlace, se ejecuta un Javascript que manipula la URL en la barra de direcciones, sin provocar una actualización de página, que a su vez hace que React Router realice una transición de página en el lado del cliente.
Pero ahora considere lo que sucede si copia y pega la URL en la barra de direcciones y se la envía por correo electrónico a un amigo. Tu amigo aún no ha cargado tu sitio web. En otras palabras, ella todavía está en fase 1. Todavía no se está ejecutando ningún React Router en su máquina. Entonces su navegador hará un solicitud del servidor para http://example.com/about
.
Y aquí es donde comienza tu problema. Hasta ahora, podías salirte con la tuya con solo colocar un static HTML en la raíz web de su servidor. Pero eso daría 404
errores para todas las demás URL cuando se solicita desde el servidor. Esas mismas URL funcionan bien en el lado del cliente, porque React Router está haciendo el enrutamiento por usted, pero fallan en el lado del servidor a menos que le haga entender a su servidor.
Combinando el enrutamiento del lado del servidor y del cliente
Si quieres el http://example.com/about
URL para que funcione tanto en el lado del servidor como en el del cliente, debe configurar rutas tanto en el lado del servidor como en el del cliente. Tiene sentido, ¿verdad?
Y aquí es donde comienzan sus elecciones. Las soluciones van desde evitar el problema por completo, a través de una ruta general que devuelve el HTML de arranque, hasta el enfoque isomórfico completo en el que tanto el servidor como el cliente ejecutan el mismo código JS.
.
Evitando el problema por completo: historial de hash
Con el historial de hash en lugar del historial del navegador, la URL de la página Acerca de se vería así:
http://example.com/#/about
La parte después del hash (#
) no se envía al servidor. Entonces el servidor solo ve http://example.com/
y envía la página de índice como se esperaba. React-Router recogerá el #/about
parte y muestra la página correcta.
Desventajas:
- URL ‘feas’
- La representación del lado del servidor no es posible con este enfoque. En lo que respecta a la optimización de motores de búsqueda (SEO), su sitio web consta de una sola página sin apenas contenido.
.
Atrapar todo
Con este enfoque, utiliza el historial del navegador, pero simplemente configura un sistema general en el servidor que envía /*
para index.html
, dándote efectivamente la misma situación que con Hash History. Sin embargo, tiene URL limpias y podría mejorar este esquema más adelante sin tener que invalidar todos los favoritos de sus usuarios.
Desventajas:
- Más complejo de configurar
- Todavía no es un buen SEO
.
Híbrido
En el enfoque híbrido, amplía el escenario general al agregar scripts específicos para rutas específicas. Puede crear algunos scripts PHP simples para devolver las páginas más importantes de su sitio con contenido incluido, de modo que Googlebot pueda al menos ver lo que hay en su página.
Desventajas:
- Aún más complejo de configurar
- Solo buen SEO para aquellas rutas a las que le das el trato especial
- Código duplicado para renderizar contenido en servidor y cliente.
.
Isomorfo
¿Qué pasa si usamos Node JS como nuestro servidor para poder ejecutar lo mismo Código JS en ambos extremos? Ahora, tenemos todas nuestras rutas definidas en una única configuración de enrutador de reacción y no necesitamos duplicar nuestro código de renderizado. Este es ‘el santo grial’ por así decirlo. El servidor envía exactamente el mismo marcado con el que terminaríamos si la transición de página hubiera ocurrido en el cliente. Esta solución es óptima en términos de SEO.
Desventajas:
- Servidor debe (poder) ejecutar JS. He experimentado con Java icw Nashorn pero no me funciona. En la práctica, principalmente significa que debe usar un servidor basado en Node JS.
- Muchos problemas ambientales complicados (usando
window
en el lado del servidor, etc.) - Curva de aprendizaje pronunciada
.
¿Qué debo usar?
Elija el que pueda salirse con la suya. Personalmente, creo que el catch-all es lo suficientemente simple de configurar, por lo que ese sería mi mínimo. Esta configuración le permite mejorar las cosas con el tiempo. Si ya está utilizando Node JS como su plataforma de servidor, definitivamente investigaría hacer una aplicación isomórfica. Sí, es difícil al principio, pero una vez que lo dominas, es una solución muy elegante al problema.
Básicamente, para mí, ese sería el factor decisivo. Si mi servidor se ejecuta en Node JS, me volvería isomorfo; de lo contrario, optaría por la solución Catch-all y simplemente la expandiría (solución híbrida) a medida que avanza el tiempo y los requisitos de SEO lo exigen.
Si desea obtener más información sobre el renderizado isomórfico (también llamado ‘universal’) con React, hay algunos buenos tutoriales sobre el tema:
- Reacciona al futuro con aplicaciones isomorfas
- El dolor y la alegría de crear aplicaciones isomórficas en ReactJS
- Cómo implementar Node + React Isomorphic JavaScript y por qué es importante
Además, para comenzar, recomiendo mirar algunos kits de inicio. Elija uno que coincida con sus opciones para la pila de tecnología (recuerde, React es solo la V en MVC, necesita más cosas para crear una aplicación completa). Empiece por mirar el publicado por el propio Facebook:
- Crear aplicación React
O elija uno de los muchos de la comunidad. Ahora hay un buen sitio que intenta indexarlos a todos:
- Elija su proyecto de inicio de React perfecto
Comencé con estos:
- React Isomorphic Starterkit
- Ejemplo de React Redux Universal Hot
Actualmente, estoy usando una versión casera de renderizado universal que se inspiró en los dos kits de inicio anteriores, pero ahora están desactualizados.
¡Buena suerte con tu búsqueda!
Las respuestas aquí son todas extremadamente útiles, lo que funcionó para mí fue configurar mi servidor Webpack para esperar las rutas.
devServer:
historyApiFallback: true,
contentBase: './',
hot: true
,
El historyApiFallback es lo que solucionó este problema para mí. Ahora el enrutamiento funciona correctamente y puedo actualizar la página o escribir la URL directamente. No hay necesidad de preocuparse por soluciones alternativas en su servidor de nodo. Obviamente, esta respuesta solo funciona si está usando webpack.
EDITAR: vea mi respuesta aquí para obtener una razón más detallada por la que esto es necesario: https://stackoverflow.com/a/37622953/5217568
Puedes cambiar tu .htaccess
archivo e inserte esto:
RewriteEngine On
RewriteBase /
RewriteRule ^index.html$ - [L]
RewriteCond %REQUEST_FILENAME !-f
RewriteCond %REQUEST_FILENAME !-d
RewriteCond %REQUEST_FILENAME !-l
RewriteRule . /index.html [L]
estoy usando react: "^16.12.0"
y react-router: "^5.1.2"
Este método es el Catch-all y es probablemente la forma más fácil de comenzar.