Comment configurer IIS pour la réécriture D'URL d'une application AngularJS en mode HTML5?

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

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

À l'application.fichier js. Je veux configurer IIS 7 pour acheminer toutes les requêtes vers

http://localhost/app/index.html

Pour que cela fonctionne pour moi. Comment dois-je faire?

Mise à Jour:

Je viens de découvrir, télécharger et installer le module IIS URL Rewrite , en espérant que cela le rendra facile et évident pour atteindre mon objectif.

Mise à Jour 2:

Je suppose que cela résume ce que j'essaie pour atteindre (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 sur cela et je me rends compte que je ne dois pas 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

Donc tout ce qui se trouve 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 règle entrante 1

La deuxième règle est:

Règle 2 de réécriture D'URL D'IIS entrant

Maintenant, quand je navigue vers localhost / app/view1, il charge la page, mais les fichiers de support (ceux du css, répertoires js, lib et partiels) sont également en cours de réécriture dans l'application / index.page html-donc tout revient comme l'index.page html quelle que soit L'URL utilisée. Je suppose que cela signifie que ma première règle, qui est censée empêcher ces URL d'être traitées par la deuxième règle, ne fonctionne pas.. des idées? ...n'importe qui? ...Je me sens si seule... :-(

123
demandé sur Dean 2012-09-27 08:24:43

5 réponses

J'écris une règle dans le web.config après {[2] } est 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.

Aussi, si vous utilisez L'API Web 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).

252
répondu Yagiz Ozturk 2015-06-16 09:28:49

Les règles entrantes IIS comme indiqué dans la question fonctionnent. J'ai dû effacer le cache du navigateur et ajouter la ligne suivante en haut de ma section <head> de l'index.page html:

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

C'est parce que j'ai plus d'une application dans localhost et donc les demandes à d'autres partiels étaient prises à localhost/app/view1 au lieu de localhost/myApplication/app/view1

Espérons que cela aide quelqu'un!

35
répondu Dean 2012-10-25 00:09:47

Dans mon cas, j'ai continué à obtenir un 403.14 après avoir configuré les règles de réécriture correctes. Il s'avère que j'avais un répertoire qui portait le même nom que l'une de mes routes D'URL. Une fois que j'ai supprimé la règle de réécriture IsDirectory, mes routes ont fonctionné correctement. Y a-t-il un cas où la suppression de la négation du répertoire peut causer des problèmes? Je ne pense pas du tout 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
répondu Josh C 2014-07-23 21:51:45

Le problème avec seulement ces deux conditions:

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

C'Est qu'ils ne fonctionnent que tant que le {REQUEST_FILENAME} existe physiquement sur le disque. Cela signifie qu'il peut y avoir des scénarios où une demande d'une vue partielle incorrectement nommée retournerait la page racine au lieu d'un 404 qui entraînerait le chargement d'angular deux fois (et dans certains scénarios, il peut provoquer une boucle infinie désagréable).

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

  <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 à n'importe quel fichier se terminant:

<conditions>
  <!-- ... -->
  <add input="{REQUEST_FILENAME}" pattern=".*\.[\d\w]+$" negate="true" />
</conditions>
7
répondu Ciprian Teiosanu 2015-11-25 20:30:21

Le moyen le plus simple que j'ai trouvé est simplement de rediriger les requêtes 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'Application Web sur le même Site Web et nécessitant des contraintes D'intégrité D'URL (par exemple authentification externe). Voici étape par étape comment faire

Index.html

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

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

Web.config

Première redirection 404 vers une page personnalisée, pour exemple "accueil / erreur"

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

Contrôleur domestique

Implémentez un simple ActionResult pour "traduire" l'entrée dans une route côté client.

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

C'est le moyen le plus simple.


Il est possible (conseillé?) pour améliorer la fonction D'erreur avec une logique améliorée pour rediriger 404 vers le client uniquement lorsque l'url est valide et laisser le déclencheur 404 normalement quand 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 client uniquement lorsqu'il commence par" /New "OU"/Show / "

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
répondu Naigel 2016-06-30 12:34:20