Skip to content

Instantly share code, notes, and snippets.

@pmNiko
Last active April 28, 2022 13:51
Show Gist options
  • Save pmNiko/49e27c6079d69cd7479a6de43758d3a4 to your computer and use it in GitHub Desktop.
Save pmNiko/49e27c6079d69cd7479a6de43758d3a4 to your computer and use it in GitHub Desktop.
React + Apache server BrouserRouter react-dom
---------------------------------- Idea -------------------------------------------
Cuando usamos la representación del lado del cliente en React(CSR) a través de
react-router-dom, lo que hacemos es simular un enrutamiento del lado del cliente. Esta
rutas virtuales son gestionadas por react-router para armar el path en la url del navegador.
Esto funciona muy bien en desarrollo.
-------------------------------- Problemática ---------------------------------------
El problema se presenta cuando utilizamos BrouserRouter de react-router y queremos recargar
la página, o acceder a un path extendido del root. Esto provoca un error 404 ya que no está
siendo manejado por el enrutador de react, sino por el servidor que está escuchando.
Cuando accedemos a una url de la app esta petición es escuchada por el servidor, este
procesa la url e intenta buscar el recurso para responder al navegador web.
Por ejemplo cuando accedemos a:
-> https://mydommain.com/ este es el root de la página, por lo
tanto el server nos responderá con el index de la app.
-> https://mydommain.com/login el server recupera el index
de la carpeta /login y lo devuelve al navegador web.
server/
|_ _ index.html
|_ _ /login
|_ _ index.html
|_ _ /home
|_ _ index.html
Pero al no tener un server que responda dichos recurso cuando intentamos acceder a:
-> https://mydommain.com/login -> recibimos un error 404.
-------------------------------------------------------------------------------------------
_______________________ SOLUCION 1 _______________________
En este punto nos encontramo con dos alternativas:
1- HashRouter
2- Configurar Apache
HashRouter: esta es la solución mas directa al usar este enrutador en lugar de
BrouserRouter, nos resuelve el conflicto de los recursos no encontrados. Lo
que hace es adosar un # al path de nuestra url y asi logra que todo caracter
sea ignorado por el procesamiento de rutas del server. De esta forma siempre
nos devolverá el index.html root de nuestra app, para dejar que el enrutador de
React se encargue de la gestion de rutas virtuales.
Ejemplo:
https://mydommain.com/#/login -> server -> https://mydommain.com/
_______________________ SOLUCION 2 _______________________
Apache Server pondra a correr los staticos que se encuentren en la carpeta
public_html en el puerto 80:http ó 443:https.
Nosotros generamos el build de la app en react para optimizarla y hacela pública,
el contenido de la carpeta build/ lo colocaremos en la carpeta public_html de Apache
pero todavia nos queda decirle que no reescriba la ruta luego del root, de esta manera
se mantendrá respondiendo con el index.html y será react-router quien gestione
las rutas virtuales de la app.
Para apache haga bien su trabajo hay que especificarle en el archivo de configuración:
/etc/apache2/sites-enabled/default-ssl.conf
<Directory "/var/www/public_html">
RewriteEngine on
# Don't rewrite files or directories
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
# Rewrite everything else to index.html to allow html5 state links
RewriteRule ^ index.html [L]
</Directory>
Hay que habilitar el modo de escritura: sudo a2enmod rewrite
y por último reiniciar el apache: sudo service apache2 restart
Recursos:
https://stackoverflow.com/questions/44038456/how-to-setup-apache-server-for-react-route
https://create-react-app.dev/docs/deployment/
___________________________________ Solución mejorada __________________________________
En lugar de editar la configuracion anterior podriamos utilizar .htaccess
IMPORTANTE!!!
Para esto debemos habilitar archivos htaccess en el server apache
fuente: https://parzibyte.me/blog/2018/06/29/habilitar-archivos-htaccess-apache/
Desde la terminal nos dirigimos a:
sudo nano /etc/apache2/apache2.conf
y editamos la siguiente linea:
<Directory /var/www/>
AllowOverride None <---
... aquí más cosas
</Directory>
Cambiamos None por All
<Directory /var/www/>
AllowOverride All
... aquí más cosas
</Directory>
Ahora si ya podemos crear el archivo .htaccess en el root de /var/www/html/.htaccess
y colocar la siguiente configuración para que siempre nos devuelva el index de nuestra app.
RewriteEngine On
RewriteBase /
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule . /index.html [L]
Esta solución funciona si tenemos el proyecto en el root de nuestra carpeta pública.
Nota: la carpeta /html representa la carpeta publica podría llamarse public_html
esta carpeta servira publicamente su contenido.
_________________________________________________________________________________________
__PLUS__
La web utiliza el protocolo https internet seguro
fuente: https://www.siteground.es/blog/que-es-https-y-para-que-sirve-guia-completa/?gclid=CjwKCAjw9qiTBhBbEiwAp-GE0VRfMeBoys4irb3XhhR6DqcOlAbTw0QaRVRZLAq7yqBqDhkm-aFl3xoCFGQQAvD_BwE
Podriamos querer redireccionar cuando accedan a nuestra página por http -----> a -----> https
para eso debemos agregar las siguientes lineas al .htaccess
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
Así como también adosar "www."
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^ https://www.%{HTTP_HOST}%{REQUEST_URI} [NE,L,R=301]
Aporte de __Gerardo Duckwitz
_________________________________________________________________________________________
Por último, el escenario anterior se enfoca en la posibilidad de tener alojada la app
en el root de nuestra carpeta public. Pero que sucede si queremos hacer un hosting
compartido, es decir allojar multiples app en nuestro server con apache.
Ver el siguiente gist: https://gist.github.com/pmNiko/d0611ab3e0722dd8d703f3478f80d65f
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment