Azure Web App에서 Vue Router HTML5 History 모드를 사용한 URL 재작성 문제
나는 Azure Web App에서 Vue SPA를 서비스한다.서버측 논리가 없다(또는 어쨌든 이 문제와 관련이 없다).
나는 HTML5 히스토리 모드로 Vue Router를 사용하고 있다.정말 잘 된다.유일한 문제는 사용자가 https://my.app.com/contacts과 같은 "직접" URL로 앱 내부의 뷰에 액세스하려고 할 때 어떻게 되는지이다.이것은 예상대로 404 Not Found를 준다.
해결 방법은 잘 알려져 있다: URL 재작성을 사용하여 이러한 요청을 앱의 루트로 라우팅한다: / 또는 /index.html.
그래서 그렇게 하려고 하는 겁니다.Azure Web Apps의 경우, 이를 수행하는 방법은 web.config 파일에 다시 쓰기 규칙을 사용하는 것이다.내 Web.config는 다음과 같다.
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="Handle History Mode and custom 404/500" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="/" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
이것은 Vue 라우터에 대한 설명서에서 바로 해제된다.
지금 사이트에 접속하면 빈 페이지가 나온다.개발자 콘솔(크롬으로 표시)을 사용하고 네트워크 탭을 확인하면 이제 스크립트 파일과 css 파일을 포함한 모든 요청이 index.html의 콘텐츠를 반환한다는 것을 알게 된다.
그래서 다시 쓰는 것은 확실히 효과가 있다, 단지 조금 과할 뿐이다.
문제는 IsFile과 IsDirectory 조건인 것 같다.이들은 RESTARY_FILENAME 서버 변수를 사용한다.이 페이지에서 나는 이것이 서버 파일 시스템에 매핑된 경로라고 이해한다.
모든 요청이 다시 작성되므로, 조건이 경로를 유효한 파일 또는 디렉토리 경로로 인식하지 못하기 때문일 것이다.
편집: 실패한 요청 추적을 사용하여 URL 다시 쓰기를 디버깅했으며 자세한 내용을 알아보십시오.다시 쓰기 모듈이 실행되면REQUEST_FILENAME
변수가 잘못됨.
웹 는 azure 웹에 D:\site\wwwroot
에는 내 가 있다 이 폴더에는 내 앱의 wwwroot 폴더가 있다.일부 구글링들은 이것이 예상대로라고 밝힌다.또한, 매핑이 올바르게 작동함 - URL 재작성 기능이 활성화되지 않은 상태에서 다음과 같은 URL 경로/img/logo.png
다음 위치에 정적 파일을 반환함D:\site\wwwroot\wwwroot\img\logo.png
.
하지만 url rewrite 모듈이 실행되면REQUEST_FILENAME
가치가 있을 것이다D:\site\wwwroot\img\logo.png
. 그 파일은 존재하지 않는다. 그래서IsFile
컨디션이 나빠지다
그렇다면 url rewrite module과 정적 파일 제공자가 경로 매핑에 대해 동의하지 않는 이유는 무엇인가?
나는 마침내 이것을 알아냈다.
ASP는.NET Core 앱은 IIS를 사용하므로 IIS가 더 이상 정적 파일을 제공하지 못하게 한다.정적 파일은 하위 디렉토리(directwroot)에 보관되며, 다음과 같이 Startup.cs에서 구성된 정적 파일 미들웨어에 의해 제공된다.
app.UseDefaultFiles();
app.UseStaticFiles();
정적 파일 미들웨어는 정적 파일이 있는 위치(원하는 경우 다른 방법으로 구성할 수 있음)를 알고 있으며, 해당 디렉토리의 파일을 가리키는 요청을 처리한다.
Azure Web Apps에서 역사적 이유로 컨텐츠 루트(여기서 .NET Core 어셈블리 및 web.config가 상주하며D:\home\site\wwwroot
기본적으로, 요청의 경우:
http:/myapp.com/img/dang.png
미들웨어는 다음 파일을 확인하십시오.
D:\home\site\wwwroot\wwwroot\img\dang.png
존재(예, 그것은 두 wwwroot).
그러나 IIS는 이를 모르고 있다.IIS에 관한 한 URL:
http:/myapp.com/img/dang.png
거주지:
D:\home\site\wwwroot\img\dang.png
그래서 이다.{REQUEST_FILENAME}
IIS 변수가 마크를 놓치고, IISFile과 IsDirectory가 실패하는 이유.
요약하자면, IIS URL 재작성은 Azure Web Apps에서 여전히 작동하지만, URL 대 파일 매핑에 따라 일치되는 것은 실패할 것이다.
다행히도(이제 알게 되었다), 다른 대안이 존재한다. 바로 URL Rewrite Middleware이다.이것은 ASP이다.NET Core 구성 요소는 의 일부로 "즉시 사용 가능"Microsoft.AspNetCore.App
메타포화화화화화화화화화화화화화화화화화하다IIS URL Rewriting이 할 수 있는 모든 것(임의 코드화된 로직으로 확장을 허용하는 것 등)을 할 수 있지만 정적 파일을 사용하여 올바르게 만들 수 있다.서류는 여기 있다.
다음은 내가 만든 다시 쓰기 규칙이다.
public class Html5HistoryRewriteRule : IRule
{
private readonly string _rewriteTo;
private readonly Regex _ignore;
public Html5HistoryRewriteRule(string rewriteTo = null, string ignore = null)
{
_rewriteTo = rewriteTo ?? "/";
_ignore = ignore != null ? new Regex(ignore) : null;
}
public void ApplyRule(RewriteContext context)
{
var request = context.HttpContext.Request;
var path = request.Path.Value;
if (string.Equals(path, _rewriteTo, StringComparison.OrdinalIgnoreCase))
return;
if (_ignore != null && _ignore.IsMatch(path))
return;
var fileInfo = context.StaticFileProvider.GetFileInfo(path);
if (!fileInfo.Exists)
{
request.Path = _rewriteTo;
context.Result = RuleResult.SkipRemainingRules;
}
}
}
정적 웹 앱 서비스를 사용하여 SPA를 구축하는 것이 더 편리한 방법이라고 생각되며, 여기서 경로에 대해 자세히 알아보십시오. https://docs.microsoft.com/en-us/azure/static-web-apps/routes
'programing' 카테고리의 다른 글
VueJs 앱에서 Firebase로 이미지 업로드 (0) | 2022.04.12 |
---|---|
VueX 상태에서 값을 직접 설정하는 방법 (0) | 2022.04.12 |
vuejs 차트j에 json 데이터 표시 (0) | 2022.04.12 |
계산된 속성에서 예기치 않은 부작용을 방지하는 방법 - VueJs (0) | 2022.04.12 |
Vue.js2 - 상위 구성 요소에 의해 $emit 이벤트가 캡처되지 않음 (0) | 2022.04.12 |