IIS'yi HTML5 modunda bir AngularJS uygulamasını yeniden yazma URL'si için nasıl yapılandırabilirim?


140

Ben angularjs tohum projesi ve ben ekledim

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

app.js dosyasına. IIS 7'yi tüm istekleri yönlendirecek şekilde yapılandırmak istiyorum

http://localhost/app/index.html

bu benim için çalışıyor. Bunu nasıl yaparım?

Güncelleme:

IIS URL Yeniden Yazma modülünü yeni keşfettim, indirdim ve yükledim .

Güncelleme 2 :

Sanırım bu ( AngularJS Geliştirici belgelerinden alınan) elde etmeye çalıştığım toplamları özetliyor :

Bu modu kullanmak için sunucu tarafında URL yeniden yazma gerekir, temel olarak uygulamanızın giriş noktasına olan tüm bağlantılarınızı yeniden yazmanız gerekir (örn. İndex.html)

Güncelleme 3:

Bu konuda hala çalışıyorum ve bazı URL'leri yeniden yönlendirmemeliyim (yeniden yazan kurallara sahip)

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

bu nedenle css, js, lib veya kısmi dizinlerdeki hiçbir şey yeniden yönlendirilmez. Diğer her şeyin app / index.html adresine yönlendirilmesi gerekir

Herkes bunu kolayca tek bir dosya için bir kural eklemek zorunda kalmadan biliyor musunuz?

Güncelleme 4:

IIS URL Yeniden Yazma modülünde tanımlanan 2 gelen kuralı var. İlk kural:

IIS URL Gelen Kuralı 1'i Yeniden Yaz

İkinci kural:

IIS URL Gelen Kuralı 2'yi Yeniden Yaz

Şimdi localhost / app / view1'e gittiğimde sayfayı yüklüyor, ancak destekleyici dosyalar (css, js, lib ve kısmi dizinlerdeki dosyalar) da app / index.html sayfasına yeniden yazılıyor - böylece her şey geliyor hangi URL kullanılırsa kullanılsın index.html sayfası olarak geri dönelim. Sanırım bu, ilk kuralım anlamına geliyor, bu URL'lerin ikinci kural tarafından işlenmesini engellediği varsayılıyor, işe yaramıyor .. herhangi bir fikir? ...kimse? ...Çok yalnız hissediyorum... :-(


Bunun için teşekkürler! Çok yararlı!
Ash Clarke

İkinci kural önemlidir: Eğer emin yönlendirme oluyor emin olmak gerekir app/index.htmlve yok app/ açıkça karşı angularjs kadar hizmet veren sayfayı tetikler. Anlamadan önce hayatımın 2 saatini kaybettim. :-)
Dexter Legaspi

ASP.NET MVC'yi kullanmanın ve RouteConfig.cs dosyasına eklemenin başka bir yolu: route.MapRoute (ad: "Varsayılan", url: "{* bir şey}", varsayılanlar: new {controller = "Home", action = "Index", }); ve HomeController Dizininiz yalnızca File ("~ / index-anyhinghere.html", "text / html") döndürür; Ardından uygulamanız IIS'den bağımsız hale gelir
Toolkit

"URL yeniden yazma modülü" Web Installer "dan kurmak zorunda kaldım. URL yeniden yazma modülü orada değilse, yeniden yükleme sırasında yeniden yazma çalışmaz. URL yeniden yazma modülünü YÜKLE. :)
Bimal Das

Yanıtlar:


289

Ben sonra web.config bir kural yazmak $locationProvider.html5Mode(true)ayarlanır app.js.

Umut, birine yardım eder.

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

İndex.html dosyasında bunu <head>

<base href="/">

Sunucuya IIS URL Yeniden Yazmayı yüklemeyi unutmayın .

Ayrıca Web API ve IIS kullanıyorsanız, API'nız www.yourdomain.com/apiüçüncü giriş (üçüncü koşul satırı) nedeniyle ise bu çalışır .


2
Bu çok faydalı oldu ve en eksiksiz olduğunu gördüm. Teşekkürler!
Mario

2
memnunum @Mario
Yağız Öztürk

5
MÜKEMMEL! Bu benim için zor bir konuydu, bunun için saatler harcadım. Teşekkürler! BAŞKA BİRİME TAVSİYE ET: <action type = "Yeniden yaz" url "/index.html" /> dizinine.html ekledim. Sonra index.html (Angular SPA için kök dizin dosyası, <base href = "/ index .html "/> Yukarıdaki kodu ele aldığımda, <base href /> ile eşleşmedi, bu yüzden düzgün çalışmadı." / (api) "kalıbı için büyük aksesuarlar da, bu kısımda tökezlemeye devam ettim.
Brad Martin

Azure web sitelerinde barındırırsam ne olur?
Araç Kiti

7
Açısal yönlendirme için bu çemberlerden atlamak zorunda olduğumuz bir şaka. Bu benim için açısal yönlendirmeyi öldürüyor. Ne dağınıklık.
user441521

38

DO soruda gösterildiği gibi IIS gelen kuralları çalışır. Tarayıcı önbelleğini temizlemek ve <head>index.html sayfasının bölümünün üstüne aşağıdaki satırı eklemek zorunda kaldım :

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

Bunun nedeni localhost'ta birden fazla uygulamam olması ve localhost/app/view1bunun yerine diğer kısmi isteklerin yerine getirilmesidir.localhost/myApplication/app/view1

Umarım bu birine yardımcı olur!


1
Buna ihtiyacım yoktu, ama soru düzenlemeleri harikaydı. Teşekkürler!
Ash Clarke

2
Ayrıca bu yararlı olabilir. Sayfayı yeniden yüklerken benim için çalıştı. Her dosya için özel kurallar olmadan: coderwall.com/p/mycbiq
Per G

@ ash-clarke'nin dediği gibi, gerekli değildir, ancak sayfadaki bağlantıların hangi "alt dizine" ait olduğu konusunda agnostik olmasına izin verdiği için iyi bir uygulamadır.
Dexter Legaspi

@PerG Yukarıdaki çözümde çalıştım ancak yeniden yükleme yapmadım, işte benim kodum: stackoverflow.com/questions/25644287/iis-url-rewrite-rules Herhangi bir fikir?
amcdnl

Bilmiyorum veya ti bazı çağrıları filtre denedim. Etrafında bir yol diğer etki alanı vb üzerinde API olması olacaktır. Ama belki bu u için bir çözüm değildir. Ama yukarıdaki bağlantıda sormaya devam edebilirsiniz. Ve belki yazar size cevap verebilir mi?
Per G

11

Benim durumumda, doğru yeniden yazma kurallarını ayarladıktan sonra 403.14 almaya devam ettim. URL rotalarımdan biriyle aynı ada sahip bir dizinim olduğu anlaşılıyor. IsDirectory yeniden yazma kuralını kaldırdığımda rotalarım düzgün çalıştı. Dizin olumsuzlamasını kaldırmanın sorunlara neden olabileceği bir durum var mı? Benim durumumda hiç düşünemiyorum. Düşünebileceğim tek durum, uygulamanızla bir dizine göz atabiliyorsanız.

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

10

Sadece bu iki koşulun olması sorunu:

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

sadece {REQUEST_FILENAME} diskte fiziksel olarak var olduğu sürece çalışırlar . Bu, yanlış adlandırılmış bir kısmi görünüm isteğinin, açısalın iki kez yüklenmesine neden olacak bir 404 yerine kök sayfayı döndüreceği senaryolar olabileceği anlamına gelir (ve belirli senaryolarda kötü bir sonsuz döngüye neden olabilir).

Bu nedenle, bu sorunların giderilmesinin zor olmasını önlemek için bazı güvenli "yedek" kurallar önerilebilir:

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

veya herhangi bir dosyayla eşleşen bir koşul :

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

1
Tüm bu yerinde ile benim sitem gayet iyi yükler, ama rota boyunca bir yolda iseniz sorunları var. Bu nedenle, tarayıcımdaki yol: 10.34.34.46/jbvdev/documents/BC498484 Başlangıçta iyi görünüyor, ancak yenilemeye basarsam , her şey kırılıyor çünkü css ve js'yi 10.34.34.46/jbvdev/documents'de aramaya başlıyor / css veya 10.34.34.46/jbvdev/documents/js Bunu nasıl çözeceğini bilen var mı?
Michael Mahony

1

Bulduğum en kolay yol, 404'ü tetikleyen istekleri istemciye yönlendirmektir. Bu, $locationProvider.html5Mode(true)ayarlandığında bile bir hashtag ekleyerek yapılır .

Bu hile, aynı Web Sitesinde daha fazla Web Uygulaması olan ve URL bütünlüğü kısıtlamaları (EG harici kimlik doğrulaması) gerektiren ortamlar için geçerlidir. İşte adım adım nasıl yapılır

index.html

<base>Elemanı doğru şekilde ayarlayın

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

web.config

Önce 404'ü özel bir sayfaya yönlendirin, örneğin "Ana Sayfa / Hata"

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

Ev denetleyicisi

ActionResultBir istemci yolunda basit bir "tercüme" girişi uygulayın.

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

Bu en basit yol.


Hata işlevini, yalnızca url geçerli olduğunda 404'ü istemciye yönlendirmek için bazı geliştirilmiş mantıkla geliştirmek ve istemcide hiçbir şey bulunmadığında 404'ün normal tetiklemesini sağlamak mümkündür (önerilir?). Diyelim ki bu açısal rotalarınız var

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

URL'yi istemciye yalnızca "/ Yeni" veya "/ Göster /" ile başladığında yönlendirmek mantıklıdır

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();
}

Bu sadece geliştirilmiş mantığın bir örneğidir, elbette her web uygulamasının farklı ihtiyaçları vardır


1

Azure Web Uygulamasına basit bir Angular 7 uygulaması dağıtmaya çalışıyorum. Sayfayı yenilediğiniz noktaya kadar her şey yolunda gitti. Bunu yaptığımda bana 500 adet taşınan içerik sunuyordum. Hem Açısal dokümanlar hem de iyi bir kaç forumda okudum, dağıtılmış çözümüme bir web.config dosyası eklemeliyim ve index.html dosyasına yeniden yazma kuralının yedeğini aldım. Saatlerce süren hayal kırıklığı ve deneme yanılma testlerinden sonra hatanın oldukça basit olduğunu gördüm: Dosya işaretlememin etrafına bir etiket eklemek.


1

Angular ve IIS ile manuel yenilemeye 404 durum kodu atma konusunda benzer bir sorun yaşadım ve en çok oy alan çözümü denedim ama bu benim için çalışmadı. Ayrıca WebDAV ve değişen işleyicileri ile uğraşmak zorunda başka çözümler bir sürü çalıştı ve hiçbiri çalıştı.

Neyse ki bu çözümü buldum ve çalıştı (ihtiyacım olmayan parçaları çıkardı). Bu nedenle, yukarıdakilerden hiçbiri sizin için veya hatta denemeden önce işe yaramazsa, bunu deneyin ve bunun iis sorunundaki açısal dağıtımınızı düzeltip düzeltmediğini görün.

Parçacığı, sitenizin kök dizinindeki web yapılandırmanıza ekleyin. Anladığım kadarıyla, 404 durum kodunu herhangi bir mirastan (applicationhost.config, machine.config) kaldırır, ardından site düzeyinde 404 durum kodu oluşturur ve özel bir 404 sayfası olarak ana sayfaya geri yönlendirir.

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <system.webServer>
    <httpErrors errorMode="Custom">
      <remove statusCode="404"/>
      <error statusCode="404" path="/index.html" responseMode="ExecuteURL"/>
    </httpErrors>
  </system.webServer>
</configuration>
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.