web-dev-qa-db-fra.com

Comment puis-je configurer IIS pour l'URL Réécriture d'une application AngularJS en mode HTML5?

J'ai le projet de semences AngularJS et j'ai ajouté 

$locationProvider.html5Mode(true).hashPrefix('!');

au fichier app.js. Je souhaite configurer IIS 7 pour acheminer toutes les demandes vers 

http://localhost/app/index.html

pour que cela fonctionne pour moi. Comment puis-je faire cela?

Mettre à jour:

Je viens de découvrir, de télécharger et d'installer le IIS module de réécriture d'URL) , en espérant que cela facilitera la réalisation de mon objectif.

Mise à jour 2:

Je suppose que cela résume ce que j'essaie de réaliser (tiré de la documentation du développeur AngularJS ):

L'utilisation de ce mode nécessite une réécriture d'URL côté serveur, fondamentalement, vous devez réécrire tous vos liens vers le point d’entrée de votre application (par exemple, index.html)

Mise à jour 3:

Je travaille toujours dessus et je me rends compte que je n'ai pas besoin de rediriger (avoir des règles qui réécrivent) certaines URL telles que 

http://localhost/app/lib/angular/angular.js
http://localhost/app/partials/partial1.html

de sorte que tout ce qui est dans les répertoires css, js, lib ou partials n'est pas redirigé. Tout le reste devra être redirigé vers app/index.html

Quelqu'un sait comment y parvenir facilement sans avoir à ajouter une règle pour chaque fichier?

Mise à jour 4:

J'ai 2 règles entrantes définies dans le module de réécriture d'URL IIS. La première règle est:

IIS URL Rewrite Inbound Rule 1

La deuxième règle est:

IIS URL Rewrite Inbound Rule 2

Maintenant, lorsque je navigue vers localhost/app/view1, la page est chargée. Cependant, les fichiers de support (ceux des répertoires css, js, lib et partiels) sont également réécrits dans la page app/index.html - tout est à venir. en tant que page index.html, quelle que soit l'URL utilisée. Je suppose que cela signifie que ma première règle, censée empêcher le traitement de ces URL par la deuxième règle, ne fonctionne pas… des idées? ...n'importe qui? ...Je me sens si seul... :-(

129
Dean

Les règles entrantes IIS, comme indiqué dans la question, fonctionnent. Je devais vider le cache du navigateur et ajouter la ligne suivante en haut de la section <head> de la page index.html:

<base href="/myApplication/app/" />

Ceci est dû au fait que j'ai plusieurs applications dans localhost et que les demandes adressées à d'autres partiels ont été transmises à localhost/app/view1 au lieu de localhost/myApplication/app/view1

Espérons que cela aide quelqu'un!

35
Dean

J'écris une règle dans web.config après que $locationProvider.html5Mode(true) soit défini dans app.js

Hope, aide quelqu'un.

  <system.webServer>
    <rewrite>
      <rules>
        <rule name="AngularJS Routes" stopProcessing="true">
          <match url=".*" />
          <conditions logicalGrouping="MatchAll">
            <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
            <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
            <add input="{REQUEST_URI}" pattern="^/(api)" negate="true" />
          </conditions>
          <action type="Rewrite" url="/" />
        </rule>
      </rules>
    </rewrite>
  </system.webServer>

Dans mon index.html, j'ai ajouté ceci à <head>

<base href="/">

N'oubliez pas d'installer IIS URL Rewrite sur le serveur.

De plus, si vous utilisez Web API et IIS, cela fonctionnera si votre API est à www.yourdomain.com/api en raison de la troisième entrée (troisième ligne de condition).

259
Yagiz Ozturk

Dans mon cas, je continuais à obtenir un 403.14 après avoir configuré les règles de réécriture correctes. Il se trouve que j'avais un répertoire qui portait le même nom que l'un de mes itinéraires d'URL. Une fois que j'ai supprimé la règle de réécriture IsDirectory, mes itinéraires ont fonctionné correctement. Existe-t-il un cas où la suppression de la négation de répertoire peut poser des problèmes? Je ne peux pas penser à aucun dans mon cas. Le seul cas auquel je peux penser est si vous pouvez parcourir un répertoire avec votre application.

<rule name="fixhtml5mode" stopProcessing="true">
  <match url=".*"/>
  <conditions logicalGrouping="MatchAll">
    <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
  </conditions>
  <action type="Rewrite" url="/" />
</rule>
9
Josh C

Le problème avec seulement ces deux conditions:

  <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
  <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />

est-ce qu'ils ne fonctionnent que tant que le {REQUEST_FILENAME}existe physiquement sur le disque . Cela signifie qu'il peut exister des scénarios dans lesquels une demande de vue partielle mal nommée renverrait la page racine au lieu d'une page 404, ce qui entraînerait le chargement deux fois de angular (et dans certains cas, cela pourrait provoquer une boucle infinie désagréable).

Ainsi, certaines règles de "repli" sûres seraient recommandées pour éviter ces problèmes difficiles à résoudre:

  <add input="{REQUEST_FILENAME}" pattern="(.*?)\.html$" negate="true" />
  <add input="{REQUEST_FILENAME}" pattern="(.*?)\.js$" negate="true" />
  <add input="{REQUEST_FILENAME}" pattern="(.*?)\.css$" negate="true" />

ou une condition qui correspond à tout fichier se terminant par

<conditions>
  <!-- ... -->
  <add input="{REQUEST_FILENAME}" pattern=".*\.[\d\w]+$" negate="true" />
</conditions>
9
Ciprian Teiosanu

Le moyen le plus simple que j'ai trouvé est simplement de rediriger les demandes qui déclenchent 404 vers le client. Cela se fait en ajoutant un hashtag même lorsque $locationProvider.html5Mode(true) est défini.

Cette astuce fonctionne pour les environnements avec plus d'applications Web sur le même site Web et nécessitant des contraintes d'intégrité d'URL (authentification externe, par exemple). Voici étape par étape comment faire

index.html

Définir l'élément <base> correctement

<base href="@(Request.ApplicationPath + "/")">

web.config

D'abord redirigez 404 vers une page personnalisée, par exemple "Home/Error"

<system.web>
    <customErrors mode="On">
        <error statusCode="404" redirect="~/Home/Error" />
    </customErrors>
</system.web>

Contrôleur de maison

Implémentez une simple ActionResult pour "traduire" une entrée dans une route client.

public ActionResult Error(string aspxerrorpath) {
    return this.Redirect("~/#/" + aspxerrorpath);
}

C'est le moyen le plus simple.


Il est possible (conseillé?) D’améliorer la fonction Error avec une logique améliorée pour rediriger 404 vers le client uniquement lorsque l’URL est valide et laisser le déclencheur 404 se déclencher normalement lorsque rien ne sera trouvé sur le client . Disons que vous avez ces routes angulaires.

.when("/", {
    templateUrl: "Base/Home",
    controller: "controllerHome"
})
.when("/New", {
    templateUrl: "Base/New",
    controller: "controllerNew"
})
.when("/Show/:title", {
    templateUrl: "Base/Show",
    controller: "controllerShow"
})

Il est logique de rediriger l'URL vers le client uniquement lorsqu'il commence par "/ Nouveau" ou "/ Afficher /"

public ActionResult Error(string aspxerrorpath) {
    // get clientside route path
    string clientPath = aspxerrorpath.Substring(Request.ApplicationPath.Length);

    // create a set of valid clientside path
    string[] validPaths = { "/New", "/Show/" };

    // check if clientPath is valid and redirect properly
    foreach (string validPath in validPaths) {
        if (clientPath.StartsWith(validPath)) {
            return this.Redirect("~/#/" + clientPath);
        }
    }

    return new HttpNotFoundResult();
}

Ceci est juste un exemple de logique améliorée, bien sûr, chaque application web a des besoins différents

1
Naigel

J'ai essayé de déployer une application simple Angular 7 sur une application Web Azure . Tout a bien fonctionné jusqu'au moment où vous avez actualisé la page. Cela me présentait un message d'erreur 500 - déplacé. J'ai lu à la fois sur la documentation angulaire et sur de nombreux forums qu'il me fallait ajouter un fichier web.config à ma solution déployée et en faire Assurez-vous que la règle de réécriture se replie dans le fichier index.html . Après des heures de frustration et de tests d'essai et d'erreur, j'ai constaté que l'erreur était assez simple: l'ajout d'une balise autour du balisage de mon fichier.

0
Kelson Martins