【问题标题】:Angular 11 - Error 404 when opening new tabAngular 11 - 打开新标签时出现错误 404
【发布时间】:2021-07-07 12:06:05
【问题描述】:

我已将我的 Angular 11 应用程序托管到远程服务器上的 IIS。 应用程序路由适用于我的 3 个路由中的 2 个。 前两个是从登录页面到“主页”页面和从“主页”到“设计”页面的路由(单击主页也可以返回主页)。这两条路线由

访问
this.router.navigate(['design']);

this.router.navigate(['home']);

从“设计”页面到“预览”页面不起作用。此路由是通过打开一个新窗口(浏览器中的新选项卡)来完成的

window.open('preview');

404 - 找不到文件或目录。 您要查找的资源可能已被删除、名称已更改或暂时不可用。

我读到我应该将我的 IIS 配置为 URL 重写,但我不明白这个概念。 从 VSCode 和 ng serve

执行此操作时,这一切都有效

我的问题是,我缺少的是 IIS 配置吗?如果是,我通过 URL 重写得到了什么 - 当我瞄准正确的 URL 时,MS 网页上的示例似乎与我无关 - http ://servername:port/preview 并收到 404 错误
还是 window.open() 的问题?

我在尝试刷新不是登录页面的页面时遇到相同的 404 - 找不到文件错误。

我已经阅读了this thread,但我仍然不需要 URL 重写

这是 app-routing.module.ts 代码:

const routes: Routes = [
    {path: '', component: LoginComponent},
    {path: 'design', component: PaletaFormaComponent},
    {path: 'preview', component: PreviewFormaComponent},
    {path: 'home', component: FirstPageComponent},
  
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

【问题讨论】:

  • window.open() 没有提供协议(http / https)将打开子实例,其路径相对于当前父实例。您确定在您的 IIS 环境中生成的路径是正确的吗?如果它作为页面的子应用程序托管(即myserver.com/AngularApp),您可能需要在 angular.json 中使用 baseHref

标签: angular http-status-code-404 angular-routing angular11


【解决方案1】:

Angular 应用程序是单页应用程序,这意味着整个应用程序位于单个页面 index.html 中

当客户端浏览器请求 /index.html 资源时,它会加载 Angular 应用程序。由于 index.html 被定义为默认页面,所以这个资源也会在客户端请求的时候被 web 服务器返回/

加载 Angular 应用程序后,如果用户单击指向 /home 路由的路由器链接,则 Angular 将更改用户浏览器上的 url 并显示所选路由的组件,但浏览器不会对服务器上不存在的 /home 资源的 HTTP 请求。浏览器上显示的页面还是index.html。

但是当用户打开一个新选项卡到 /home 或按 F5 时,浏览器会向服务器请求 /home 资源,因为它不存在,它会返回 404 错误。

为了使应用程序正常工作,服务器需要通过返回 index.html 来响应对 /home 的请求。这样,当用户请求 /home 时,他会加载 angular 应用程序,一旦将其加载到浏览器上,就会启动 angular 路由并显示 home 组件。

所以服务器需要返回 index.html,但是 Angular 应用程序会使用 index.html 以外的其他资源,例如脚本、样式、图像、API... 因此,只有当它不是对这些资源之一的请求时,服务器才需要返回 index.html。 一种方法是使用 URL 重写规则。在 IIS 中,您可以这样做:

  <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" />
        <add input="{REQUEST_URI}" pattern="^/(api)" negate="true" />
      </conditions>
      <action type="Rewrite" url="/" />
    </rule>

当请求不匹配文件、目录且不以/api开头时,这些规则将使服务器返回资源/(即index.html)

这也可以在不重写 url 的情况下通过将此行为直接编码到 Web 服务器中来完成。在 aspnet 核心中,这是通过 SpaStaticFiles 中间件完成的。

当您使用 ng serve 运行应用程序时,angular cli 会启动一个已经配置为执行 URL 重写的 Web 服务器。这就是为什么 localhost 没有这个问题。

【讨论】:

  • 我们在使用 URL 重写时发现的另一个问题是 Microsoft Deployed 没有正确安装 IIS 模块,因此如果您对 IIS Rewrite 有任何问题,请检查所有内容是否正确安装为好吧。 @J.Loscos,你的回答是一切,然后是一些,非常感谢你
猜你喜欢
  • 2019-11-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-06
  • 1970-01-01
  • 2017-12-01
  • 1970-01-01
  • 2021-07-21
相关资源
最近更新 更多