Angular 2在IIS上托管:HTTP错误404

32

我有一个简单的应用程序,其中只有一个组件,它希望从URL中获取特定参数。 应用程序中只有一个路由:

const appRoutes: Routes = 
                       path: 'hero/:userId/:languageId',component: HeroWidgetComponent }];

在 Index.html 文件中,我在头部有这样一行代码:<base href="/">

我正在使用 webpack,在开发环境下运行正常,可以通过以下 url 进行访问:http://localhost:4000/hero/1/1.

然而,当我打包应用并将其放到 IIS 上托管时,尝试浏览相同的 url 时出现以下错误:

HTTP Error 404.0 - Not Found
The resource you are looking for has been removed, had its name changed, or is temporarily unavailable.

如果我删除所有路由并只浏览以下内容:http:localhost:4200,该应用程序可以正常工作。


1
你的 IIS 服务器需要正确配置,以便将所有的 Angular 路由重定向到 index.html(或触发 Angular 应用的 HTML 文件)。不幸的是,我不是 IIS 服务器专家,所以我无法给出确切的答案来解决这个问题。 - tftd
值得注意的是,许多托管提供商允许您使用他们的仪表板设置自定义错误页面。在这种情况下,您可以将“/”作为404错误的路径添加到您的Angular应用程序中,以便所有路由都由您的应用程序处理。 - undefined
6个回答

76

我们需要通过添加重写规则使IIS回退到index.html。

步骤1: 安装IIS URL Rewrite模块。

步骤2: 在web.config中添加重写规则。

   <?xml version="1.0" encoding="utf-8"?>
    <configuration>
      <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" />   
              </conditions>
              <action type="Rewrite" url="/" />
            </rule>
          </rules>
        </rewrite>
      </system.webServer>
    </configuration>

2
@mapussah,可能是因为这个模块已经安装了。 - Hussein Salman
1
你好,我按照相同的步骤操作,但在我的本地IIS中仍然出现404错误。我从答案中给出的链接下载了URL重写,执行后显示已经安装。请问我错过了什么?我使用Angular 4、@angular/cli、C# Web API和VS 2015开发应用程序。 - Prashant Kankhara
2
如何在IIS网站配置下进行更改,而无需使用web.config文件。 - RollRoll
我正在同一位置上托管REST Api... 但是在不同的文件夹中(例如rest),之后我得到错误:无法加载资源:服务器响应了405状态(方法不允许)。 - Ivan Salo
干得好,太棒了。 - HOÀNG LONG
显示剩余4条评论

7

步骤3:将web.config链接添加到angular.json中:(因为在ng build之后会跳过它)

"architect": {
                "build": {
                    "builder": "@angular-devkit/build-angular:browser",
                    "options": {
                         ..........
                        "assets": [
                            "src/favicon.ico",
                            "src/assets",
                            **"src/web.config"**
                        ]

4

4

无需安装IIS URL Rewrite

正如@tftd在评论中解释的那样,当IIS找不到匹配的文件或文件夹时,它需要知道如何处理请求。

您可以配置IIS,在请求路径和/或参数(也称为深链接)没有找到匹配项时返回index.html

手动方式在IIS中进行配置

  1. 在IIS管理器中选择您的站点
  2. IIS部分中打开Error Pages图标
  3. 打开状态代码404列表项
  4. 选择在此站点上执行URL单选按钮
  5. 输入您的SPA根路径,例如:'/index.html'
  6. 点击“确定” Edit Custom Error

不需要重新启动应用程序池,只需浏览到您的深链接。服务器将使用状态代码200进行响应。(在2021年使用具有IIS 10的Windows Server 2016进行测试)。

如果你的SPA不是以/index.html为根目录,请在第5步中输入你的应用程序所在的文件夹或文件。

上述手动过程会添加或更改web.confighttpErrors部分:

<configuration>
    <system.webServer>
        <httpErrors>
            <remove statusCode="404" subStatusCode="-1" />
            <error statusCode="404" prefixLanguageFilePath="" path="/index.html" responseMode="ExecuteURL" />
        </httpErrors>
    </system.webServer>
</configuration>

为了在下一次部署后不丢失这个更改,请确保你的发布流水线保持web.config中的httpErrors部分如上所示。
这适用于AngularReact应用程序。

对我来说,只需简单添加就可以使用了。我的 Web 开发应用程序位于默认网站下,只需将 /index.html 替换为 /web-dev/,现在当刷新浏览器时,它会保持在同一路由/页面上。 - sudurrani

3

通过在基本URL后添加#来修改Angular路由:

http://localhost:4200/yourApp#/subPageRoute

在app-routing.module.ts文件中,与RouterModule.forRoot相应的行添加", { useHash: true }"。

RouterModule.forRoot(routes, { useHash: true })

这样,IIS就会认为 # 符号后面的所有内容都是页面上的某个标识符,并忽略它。


尽管这个解决方案已经过时,但它仍然可以集成到一个共享服务器上的项目中,而你无法安装 "Rewrite"。 - Haim Tabak

0

将此 web.config 文件复制并粘贴到您的根目录中

<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
 
  <rewrite>
    <rules>
      <rule name="Angular Routes" 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="./index.html" />
      </rule>
    </rules>
  </rewrite>
 
</system.webServer>
</configuration>

这个回答可以改进。您能解释一下为什么原帖作者应该粘贴这个配置文件吗?这个方法为什么会起作用并解决问题呢? - Malcor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接