HTML5 모드에서 AngularJS 애플리케이션을 URL 재 작성을 위해 IIS를 구성하려면 어떻게해야합니까?


140

나는이 AngularJS와 종자 프로젝트를 내가 추가 한

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

app.js 파일에. 모든 요청을 라우팅하도록 IIS 7을 구성하고 싶습니다.

http://localhost/app/index.html

그래서 이것은 나를 위해 작동합니다. 어떻게해야합니까?

최신 정보:

방금 IIS URL Rewrite 모듈을 발견, 다운로드 및 설치했습니다. 이것이 목표를 달성하는 것이 쉽고 분명해지기를 바랍니다.

업데이트 2 :

이것이 내가 달성하려는 것을 요약 한 것 같습니다 ( AngularJS Developer documentation 에서 가져옴 ).

이 모드를 사용하려면 서버 측에서 URL을 다시 작성해야합니다. 기본적으로 모든 링크를 응용 프로그램의 진입 점으로 다시 작성해야합니다 (예 : index.html)

업데이트 3 :

나는 여전히이 문제를 해결하고 있으며 다음과 같은 특정 URL을 리디렉션하지 않아야합니다 (규칙을 다시 작성해야 함).

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

따라서 css, js, lib 또는 partials 디렉토리에있는 항목은 경로 재 지정되지 않습니다. 그 밖의 모든 것은 app / index.html로 리디렉션해야합니다.

누구나 단일 파일마다 규칙을 추가하지 않고도 쉽게 달성하는 방법을 알고 있습니까?

업데이트 4 :

IIS URL 다시 쓰기 모듈에 2 개의 인바운드 규칙이 정의되어 있습니다. 첫 번째 규칙은 다음과 같습니다.

IIS URL 다시 쓰기 인바운드 규칙 1

두 번째 규칙은 다음과 같습니다.

IIS URL 다시 쓰기 인바운드 규칙 2

이제 localhost / app / view1로 이동하면 페이지가로드되지만 지원 파일 (css, js, lib 및 partials 디렉토리의 파일)도 app / index.html 페이지에 다시 작성되므로 모든 것이오고 있습니다. 어떤 URL을 사용하든 index.html 페이지로 돌아갑니다. 이 규칙이 두 번째 규칙으로 처리되지 않도록하는 첫 번째 규칙을 의미한다고 생각합니다. 어떤 아이디어입니까? ...누군가? ...몹시 외로워... :-(


감사합니다! 매우 도움이되었습니다!
Ash Clarke

두 번째 규칙은 매우 중요하다 : 당신이 확실이 라우팅 있다고해야 app/index.html하고 하지 app/ 명시 적으로 AngularJS와를 제공하는 페이지를 트리거합니다. 내가 알아 차리기 전에 나는 2 시간을 잃었다. :-)
Dexter Legaspi

ASP.NET MVC를 사용하고 RouteConfig.cs에 추가하는 다른 방법 : routes.MapRoute (name : "Default", url : "{* anything}", 기본값 : new {controller = "Home", action = "Index", }); HomeController 색인은 File ( "~ / index-anyhinghere.html", "text / html"); 그러면 앱이 IIS와 무관하게됩니다
툴킷

" 'Web Installer'에서 URL 재 작성 모듈"을 설치해야했습니다. URL 다시 쓰기 모듈이 없으면 다시로드하는 동안 다시 쓰기가 작동하지 않습니다. URL 재 작성 모듈을 설치하십시오. :)
Bimal Das

답변:


289

$locationProvider.html5Mode(true)설정된 후 web.config에 규칙을 작성합니다 app.js.

희망은 누군가를 도와줍니다.

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

내 index.html에서 이것을 추가했습니다. <head>

<base href="/">

서버에 IIS URL 다시 쓰기 를 설치하는 것을 잊지 마십시오 .

또한 웹 API 및 IIS를 사용하는 경우 API가 www.yourdomain.com/api세 번째 입력 (세 번째 조건)으로 인해 작동합니다 .


2
이것은 매우 유용했으며 가장 완벽한 것으로 나타났습니다. 감사!
Mario

2
다행이 @Mario하는 데 도움이
Yagiz Ozturk

5
완전한! 이것은 나를 위해 힘든 문제였습니다.이 작업에 몇 시간을 보냈습니다. 감사! 다른 사람에게 조언 : index.html을 <action type = "Rewrite"url "/index.html"/>에 추가 한 다음 index.html (Angular SPA의 루트 디렉토리 파일 인 <base href = "/ index .html "/> 위의 코드를 처리 할 때 <base href />와 일치하지 않아 제대로 작동하지 않습니다."/ (api) "패턴에 대한 거대한 소품도 그 부분에 걸려 넘어졌습니다.
Brad Martin

Azure 웹 사이트에서 호스팅하면 어떻게 되나요?
툴킷

7
각도 라우팅을 위해 이러한 후프를 뛰어 넘어야한다는 농담입니다. 이것은 나를 위해 각도 라우팅을 죽입니다. 엉망이야
user441521

38

질문 DO에 표시된 IIS 인바운드 규칙이 작동합니다. 브라우저 캐시를 지우고 <head>index.html 페이지 섹션 상단에 다음 줄을 추가해야했습니다 .

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

이것은 localhost에 둘 이상의 응용 프로그램이 있으므로 다른 부분에 대한 요청이 localhost/app/view1대신 요청 되었기 때문 입니다.localhost/myApplication/app/view1

잘만되면 이것은 누군가를 돕는다!


1
나는 이것을 필요로하지 않았지만 질문 편집은 훌륭했습니다. 감사!
Ash Clarke

2
또한 이것은 유용 할 수 있습니다. 페이지를 다시로드 할 때 나를 위해 일했습니다. 모든 파일에 대해 특별한 규칙이없는 경우 : coderwall.com/p/mycbiq
Per G

@ ash-clarke이 말했듯이, 반드시 필요한 것은 아니지만 어쨌든 페이지의 링크가 어떤 "하위 디렉토리"에 속하는지 알 수 없기 때문에 좋은 습관입니다.
Dexter Legaspi

@PerG 위의 솔루션이 작동하지만 다시로드되지는 않았습니다. 내 코드는 다음과 같습니다. stackoverflow.com/questions/25644287/iis-url-rewrite-rules 어떤 아이디어?
amcdnl

특정 통화를 걸러 내거나 몰랐습니다. 다른 도메인 등에서 API를 사용하는 것이 좋습니다. 그러나 아마도 이것은 u의 해결책이 아닙니다. 그러나 위 링크에서 계속 요청할 수 있습니다. 저자가 대답 할 수 있을까요?
G 당

11

제 경우에는 올바른 다시 쓰기 규칙을 설정 한 후에 403.14가 계속 발생했습니다. 내 URL 경로 중 하나와 동일한 이름의 디렉토리가있는 것으로 나타났습니다. IsDirectory 다시 쓰기 규칙을 제거한 후에는 경로가 올바르게 작동했습니다. 디렉토리 부정을 제거하면 문제가 발생할 수 있습니까? 내 경우에는 아무것도 생각할 수 없습니다. 내가 생각할 수있는 유일한 경우는 앱으로 디렉토리를 탐색 할 수있는 경우입니다.

<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

이 두 가지 조건 만있는 문제 :

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

{REQUEST_FILENAME} 디스크에 물리적으로 존재 하는 한에만 작동합니다 . 이는 이름이 잘못 지정된 부분 뷰에 대한 요청이 404 대신 루트 페이지를 반환하여 각도가 두 번로드되는 시나리오가있을 수 있음을 의미합니다 (특정 시나리오에서는 불쾌한 무한 루프가 발생할 수 있음).

따라서 다음과 같은 어려운 문제 해결을 피하기 위해 안전한 "대체"규칙을 사용하는 것이 좋습니다.

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

또는 파일 끝과 일치 하는 조건 :

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

1
이 모든 것을 갖추면 내 사이트가 정상적으로로드되지만 경로를 따라 경로에 있으면 문제가 있습니다. 따라서 브라우저의 경로가 10.34.34.46/jbvdev/documents/BC498484 인 경우 처음에는 정상적으로 표시되지만 새로 고침을 누르면 10.34.34.46/jbvdev/documents 에서 CSS와 js를 찾기 시작하기 때문에 모든 것이 중단됩니다. / css 또는 10.34.34.46/jbvdev/documents/js 이 문제를 해결하는 방법을 아는 사람이 있습니까?
Michael Mahony

1

내가 찾은 가장 쉬운 방법은 404를 트리거하는 요청을 클라이언트로 리디렉션하는 것입니다. 이 $locationProvider.html5Mode(true)설정되어 있어도 해시 태그를 추가하면 됩니다.

이 트릭은 동일한 웹 사이트에 더 많은 웹 응용 프로그램이 있고 URL 무결성 제약 조건 (EG 외부 인증)이 필요한 환경에서 작동합니다. 단계별로 수행하는 방법은 다음과 같습니다.

index.html

<base>요소를 올바르게 설정하십시오

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

web.config

먼저 404를 맞춤 페이지로 리디렉션합니다 (예 : "홈 / 오류").

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

가정용 컨트롤러

ActionResult클라이언트 측 경로에서 입력을 "번역" 하는 간단한 구현

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

이것이 가장 간단한 방법입니다.


URL이 유효 할 때만 404를 클라이언트로 리디렉션하고 클라이언트에서 아무것도 발견되지 않을 때 404가 정상적으로 트리거되도록하는 향상된 로직으로 오류 기능을 향상시킬 수 있습니다 (권장?). 이 각도 경로가 있다고 가정 해 봅시다.

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

"/ New"또는 "/ Show /"로 시작할 때만 URL을 클라이언트로 리디렉션하는 것이 좋습니다.

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

이것은 개선 된 논리의 예일뿐입니다. 물론 모든 웹 응용 프로그램마다 요구 사항이 다릅니다.


1

간단한 Angular 7 응용 프로그램을 Azure Web App에 배포하려고했습니다. 페이지를 새로 고칠 때까지 모든 것이 잘 작동했습니다. 그렇게하면 500 오류가 발생했습니다. 콘텐츠가 이동했습니다. Angular 문서와 몇 가지 포럼에서 읽은 배포 된 솔루션에 web.config 파일을 추가하고 다시 쓰기 규칙이 index.html 파일로 대체되는지 확인해야합니다. 몇 시간의 좌절과 시행 착오 테스트를 거친 후 파일 마크 업 주위에 태그를 추가하면 오류가 매우 간단하다는 것을 알았습니다.


1

Angular 및 IIS와 비슷한 문제가 발생하여 수동 새로 고침에서 404 상태 코드가 발생하고 가장 많이 투표 된 솔루션을 시도했지만 그 방법이 효과가 없었습니다. 또한 WebDAV 및 처리기 변경을 처리 해야하는 다른 많은 솔루션을 시도했지만 아무것도 작동하지 않았습니다.

운 좋게도이 솔루션을 찾았고 효과가 없었습니다 (필요하지 않은 부분을 찾았 습니다). 따라서 위의 방법 중 어느 것도 효과가 없거나 시도하기 전에 시도하면 iis 문제에 대한 각도 배포가 해결되는지 확인하십시오.

사이트의 루트 디렉토리에있는 웹 구성에 스 니펫을 추가하십시오. 내 이해에서 상속 (applicationhost.config, machine.config)에서 404 상태 코드를 제거한 다음 사이트 수준에서 404 상태 코드를 만들고 사용자 지정 404 페이지로 홈 페이지로 다시 리디렉션합니다.

<?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>
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.