J'essaie de comprendre comment configurer le serveur Apache Tomcat pour servir angular avec des liens profonds. Par exemple:
Un serveur statique retourne systématiquement index.html lorsqu'il reçoit une demande de mysite.com/. Mais il rejette mysite.com/heroes/42 et renvoie une erreur 404 - Introuvable sauf s'il est configuré pour renvoyer index.html à la place.
Je veux servir angular sur localhost/angular, j'ai essayé de suivre:
1) Construisez angular avec:
ng build --prod --base-href .
2) Copiez le contenu du dossier de construction (par défaut: dist) dans $ ApacheLocation/webapps/angular
3) Ajoutez RewriteRules à $ ApacheLocation/conf/Catalina/localhost/rewrite.config
# If an existing asset or directory is requested go to it as it is
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteRule ^ - [L]
# If the requested resource doesn't exist, use index.html
RewriteRule ^\/angular\/.*$ /angular/index.html
4) Ajout d'une valve juste en dessous de la balise Host
<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true">
<Valve className="org.Apache.catalina.valves.rewrite.RewriteValve"/>
5) Démarrer le serveur Tomcat et aller sur localhost/angular me donnera:
ncaught SyntaxError: jeton inattendu < pour tous les bundles .js (par exemple main.bundle.js)
Si je n'inclus pas de règles de réécriture, Tomcat servira localhost/angular comme prévu mais donnera 404 sur les liens profonds.
Ma configuration d'installation:
J'ai réussi à résoudre ce problème, par exemple http: // localhost: 8080/angular/player/detail/4 avec les étapes suivantes:
1) Build angular avec: ng build --prod -bh ./ -d/angular
2) Copiez le contenu de l'application intégrée dans $ ApacheLocation/webapps/angular
3) Réécrire la règle:
RewriteCond %{REQUEST_PATH} !-f
RewriteRule ^/angular/(.*) /angular?path=$1
4) Configuration de la navigation sur app.component.ts:
constructor(private activatedRoute: ActivatedRoute, private router: Router) { }
ngOnInit() {
const path = this.activatedRoute.snapshot.queryParams['path'];
const navigateTo = '/' + path;
if (path) {
this.router.navigate([navigateTo]);
}
}
Vous pouvez trouver le projet de test ici: https://github.com/avuletica/test
Explication des règles de réécriture:
# %{REQUEST_PATH} corresponds to the full path that is used for mapping.
# ! NOT character
# '-f' (is regular file) Treats the TestString as a pathname and tests whether or not it exists, and is a regular file.
# ^ matches the beginning of the string or line
# . matches any charceter except line breaks
# * match 0 or more of the preceding token
Donc, fondamentalement, s'il n'y a pas de fichier sur/angulaire/quoi que ce soit, Tomcat envoie le chemin complet en tant que chaîne de requête à angular et à partir de cette requête param angular gère le routage).
Pour résoudre le problème de lien profond lors du déploiement de angular (avec routage PathLocationStrategy) sur le serveur Apache Tomcat (8, 9) -
server.xml -
...
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
<Valve className="org.Apache.catalina.valves.rewrite.RewriteValve" />
...
</Host>
...
rewrite.config note -/hello/est le chemin de contexte de l'application angular sur Tomcat)
RewriteCond %{REQUEST_PATH} !-f
RewriteRule ^/hello/(.*) /hello/index.html
J'ai documenté ce problème dans mon article - --- (Correction d'un problème de lien profond - Déploiement angular sur le serveur Tomcat
Remarque - aucune configuration côté client n'est nécessaire pour y parvenir (à l'exception de la configuration par défaut issue de CLI). Tout le routage côté client est géré par le module de routage Angular.