web-dev-qa-db-fra.com

Localisation dynamique des actifs dans Angular

Mon application va être utilisée sur plusieurs machines et peut se trouver à un endroit différent à chaque fois. Par exemple, la route de départ peut être située à l’un des emplacements suivants:

localhost: 9000/home

localhost: 9000/abc/home

localhost: 2000/yet/another/location/home

Je veux donc m'assurer que mon application fonctionnera où qu'elle soit pour trouver ses actifs. Tous mes chemins sont relatifs, alors j'espère que c'est un pas dans la bonne direction, comme ceci:

<link rel="stylesheet" href="assets/global-styles.css">

et dans mes modèles de composants, comme ceci:

<img src="assets/components/dashboard/images/foo.png" />

Voici ce que j'ai essayé jusqu'à présent:

J'ai modifié mon attribut <base> afin de saisir manuellement la partie de l'URL après le port et avant "home" comme suit:

<html>
    <head>
    <script>
        // manually sets the <base> tag's href attribute so the app can be located in places other than root
        var split = location.pathname.split('/');
        var base = "";
        for (var i = 0; i < split.length - 1; i++) {
            base += split[i];
            if (i < split.length - 2) {
                base += "/";
            }
        }
        window['_app_base'] = base;
        document.write("<base href='" + base + "' />");
    </script>
        ....

Jusqu'ici, par exemple, si l'utilisateur a chargé la page d'accueil sur localhost: 9000/hello/home, la balise <base> ressemblera à ceci:

<base href='/hello' />

Ce code définit également une variable sur cette même valeur, que j'utilise ensuite dans app.module.ts pour fournir également une nouvelle valeur de base:

importer {APP_BASE_HREF} depuis '@ angular/common';

@NgModule({
    declarations: [...],
    imports: [...],
    providers: [
        ...,
        { provide: APP_BASE_HREF, useValue: window['_app_base'] || '/' }
    ]
});

Cependant, malgré tout cela, l'application recherche toujours des actifs dans le dossier des actifs, qui, selon elle, se trouve toujours à l'emplacement racine.

GET http://localhost:9000/assets/ionic-styles.css net::ERR_ABORTED
GET http://localhost:9000/inline.bundle.js net::ERR_ABORTED
GET http://localhost:9000/assets/font-awesome-4.6.3/css/font-awesome.min.css net::ERR_ABORTED
GET http://localhost:9000/assets/bootstrap.min.css net::ERR_ABORTED
GET http://localhost:9000/assets/global-styles.css net::ERR_ABORTED
GET http://localhost:9000/polyfills.bundle.js net::ERR_ABORTED
GET http://localhost:9000/styles.bundle.js net::ERR_ABORTED
GET http://localhost:9000/vendor.bundle.js net::ERR_ABORTED

Qu'est-ce que je rate? J'ai également vu des personnes adopter une approche dans laquelle elles spécifient un chemin dans leur commande ng build ... est-ce nécessaire en plus de tout ce qui précède? J'aimerais vraiment éviter de créer une version distincte pour chaque installation, mais si c'est ce que ça prend, merci de me le faire savoir.

Merci.

UPDATE: Après quelques jours de frustration, mon application fonctionne à l'aide du code présenté dans la question ci-dessus. Il s'avère que je n'avais besoin que du <script> dans mon <head> pour modifier le <base>. Il n'était pas nécessaire d'ajouter APP_BASE_HREF aux fournisseurs ngModule. Cependant, l'ajout de APP_BASE_HREF ne casse rien non plus ...

C’est l’un de ces problèmes où il a «fonctionné» après avoir abandonné le problème pendant une semaine et y revenir. Peut-être y avait-il une sorte de problème de cache en cours? Après tout, j’avais essayé de mettre à jour le <base> la semaine dernière, mais il cherchait toujours au mauvais endroit les ressources. Bien que j'aie effacé le cache du navigateur plusieurs fois la semaine dernière pour tenter de résoudre ce problème, je ne suis donc pas sûr que le cache soit réellement à l'origine du problème. 

Je suis désolé que cette réponse ne soit pas utile pour les personnes confrontées à ce problème à l'avenir. Je n'ai vraiment aucune idée de ce qui a résolu le problème. Ma meilleure hypothèse est que l'une des réponses ci-dessous vous orientera probablement dans la bonne direction. Il semble que peu importe ce que j'ai essayé, cela ne fonctionnait pas pour une raison inconnue.

Si vous êtes confronté à ce problème et avez une question spécifique, n'hésitez pas à m'envoyer un message ou à laisser un commentaire, et je vous dirai comment les choses se passent.

6
David

Il vous suffit de faire le base href suivant dans votre index.html

<base href="./">

que vous pouvez faire soit manuellement, soit en construisant comme

ng build --base-href ./

Vous n'avez rien d'autre à faire que de copier le contenu du répertoire dist dans le répertoire /whatever/is/your/root/ de votre serveur.

Maintenant, vous pouvez accéder à votre application angulaire avec l'URL 

localhost:port/whatever/is/your/root/index.html

METTRE &AGRAVE; JOUR

Vous voudrez probablement faire plus de choses sur votre serveur. Mais, comment vous allez, dépendra entièrement de la technologie que vous utilisez sur votre serveur.

  1. Définissez localhost:port/whatever/is/your/root/index.html comme page d'accueil par défaut.

  2. Pour que les URL de route html5 de votre application angulaire fonctionnent correctement lors de l'actualisation du navigateur, vous devez transférer toutes les demandes à URL localhost:port/whatever/is/your/root/** à localhost:port/whatever/is/your/root/index.html. Notez que vous devez transférer la demande et ne pas envoyer de redirection.

2
vsoni

C'est comme ça que l'URL fonctionne dans les navigateurs. Vous pouvez les changer avec un tuyau . Considérant que votre valeur injectée fonctionne comme prévu, cela doit fonctionner. En outre, il doit s'agir de chaînes telles que 'APP_BASE_HREF' dans le module.

 @Pipe({
  name: 'assetspipe'
})
export class AssetspipePipe implements PipeTransform {
      baseUrl: string;
      constructor(@Inject('APP_BASE_HREF') baseHref: string) {
        this.baseUrl = baseHref;
      } 

      transform(value: string) {
        const newval = this.baseUrl + value;
           return newval;
      } 

}

puis dans votre composant:

<img src="{{'assets/components/dashboard/images/foo.png' | assetspipe}}"/>

le tuyau devrait ajouter le baseurl comme préfixe. 

Vérifiez également this thread. Votre implémentation peut avoir un problème avec le chargement de bundles. 

2
Okan Aslankan