web-dev-qa-db-fra.com

Déployer angular sur le problème de liens profonds Apache Tomcat 404

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:

  • Version Tomcat 9.0.0.M26
  • version angulaire 4.4.2
  • @ angulaire/cli: 1.4.2
  • nœud: 8.5.0
  • npm: 5.4.2
  • os: linux x64
11
Ante Vuletic Antic

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).

7
Ante Vuletic Antic

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) -

  1. Configurer RewriteValve dans server.xml
  2. Écrivez la règle de réécriture dans rewrite.config

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.

1