角度路由IIS - 重写仅适用于浅路径



关于SO有很多问题。我读过很多,其中大多数都指向配置 IIS 重写的示例 web.config 文件。最接近我问题的帖子似乎是这样的:

Angular 2 应用程序在移动到 IIS 虚拟目录时不起作用

然而,这已经被否决了两次,似乎已经死了,所以与其试图复活它,我想我会在这里解释我的问题。

该代码作为 ASP.NET 应用程序托管在: http://127.0.0.1/angular-app/

Angular 代码是通过命令构建的:ng build --base-href ./,生成的/dist/文件夹是托管在上述本地地址的代码。

IIS 应用程序具有以下 web.config 文件:

<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.5.2" />
<httpRuntime targetFramework="4.5.2" />
</system.web>
<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>
</configuration>

通过此设置,这些 URL 将返回预期的内容:

http://127.0.0.1/angular-app/

http://127.0.0.1/angular-app/dashboard/

http://127.0.0.1/angular-app/heros/

URL 重写规则正确指向应用程序基目录,因此会查找vendor.js, main.js等文件。

但是,对于较长的URI,重写规则似乎只会在链接文件的文件夹路径上后退一步。例如网址

http://127.0.0.1/angular-app/heros/20/

将正确返回index.html并显示"应用程序加载">

然而,深入挖掘它似乎试图从基本目录加载vendor.js, main.js等文件 http://127.0.0.1/angular-app/heros/,只是一步而不是直接从路由。

然后,这些链接也会重定向回index.html文件,因此不会将任何脚本传递到浏览器。

我试过使用

<base href="/">

而不是./并相应地修改重写规则,但这具有始终将内容重定向到 http://127.0.0.1/的效果

正如链接帖子中所建议的,我将基本 href 更改为:

<base href="/angular-app/">

这会从正确的位置返回index.html。 但是,仍然从服务器根目录(http://127.0.0.1/)请求vendor.js, main.js等文件

我假设我可以通过简单地手动编辑index.html文件以指向根目录的正确路径来解决此问题,但这似乎是黑客而不是修复。

谁能解释一下这里发生了什么,为什么:

<base href="/">

为大多数人工作,但不是我?

我的解决方案,

利用.aspx页面的强大功能停止使用相对路径。 这样一切都可以硬编码

我在/src/文件夹中创建了一个新的默认.aspx页面,并从/dist/index.html 复制生成的代码

然后将此代码调整为:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="src_Default" %>
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>angular-app</title>
<base href="<%=ResolveUrl("~/")%>">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="<%=ResolveUrl("~/favicon.ico")%>" >
</head>
<body>
<app-root>Loading...</app-root>
<script type="text/javascript" src="<%=ResolveUrl("~/inline.bundle.js")%>"></script>
<script type="text/javascript" src="<%=ResolveUrl("~/polyfills.bundle.js")%>"></script>
<script type="text/javascript" src="<%=ResolveUrl("~/styles.bundle.js")%>"></script>
<script type="text/javascript" src="<%=ResolveUrl("~/vendor.bundle.js")%>"></script>
<script type="text/javascript" src="<%=ResolveUrl("~/main.bundle.js")%>"></script></body>
</html>

本质上是解析服务器上 asp.net 应用程序的 bae,并将其写入所有引用 - 包括<base href="" />

然后更改.angular-cli.json文件,使其在生成时将默认.aspx和默认.aspx.cs文件复制到/dist/文件夹

"assets": [
"Default.aspx",
"Default.aspx.cs",
"web.config",
"assets",
"favicon.ico"
],

在这个过程中,我还发现这是复制我的 web.config 文件的正确方法,我一直在手动执行此操作 - 所以这是一种解脱。

经过一些IIS调整以确保默认.aspx在列出一切正常的默认文档中更高。

现在似乎是一个解决方案,但如果这些文件被版本控制,我可以看到这成为一个问题......但是当我到达那座桥时/如果我到达它,我会过那座桥。

最新更新