首页 文章

通过浏览器刷新时出现Angular 2:404错误[重复]

提问于
浏览
122

这个问题在这里已有答案:

我是Angular 2的新手 . 我将我的单页应用程序存储在名为"myapp"的文件夹中 . 我已将基数中的URL更改为http://example.com/myapp/ .

我的项目有两页 . 所以我实现了Angular 2路由 . 我将默认页面设置为登录 . 当我在浏览器中输入 http://example.com/myapp/ 时,它会自动重定向到 http://example.com/myapp/login . 但如果刷新该页面我会收到 404 错误,说找不到 http://example.com/myapp/login .

但是,如果我使用lite服务器运行我的项目,一切正常 . 在这种情况下,index.html中的URL将为 "/" . 如何解决?

7 回答

  • 5

    对于使用Angular 2 rc4或更高版本的人来说,看起来LocationStrategy已经从路由器转移到了普通路由器 . 你必须从那里导入它 .

    另请注意'provide'行周围的花括号 .

    main.ts

    // Imports for loading & configuring the in-memory web api
    import { XHRBackend } from '@angular/http';
    
    // The usual bootstrapping imports
    import { bootstrap }      from '@angular/platform-browser-dynamic';
    import { HTTP_PROVIDERS } from '@angular/http';
    
    import { AppComponent }         from './app.component';
    import { APP_ROUTER_PROVIDERS } from './app.routes';
    import { Location, LocationStrategy, HashLocationStrategy} from '@angular/common';
    
    bootstrap(AppComponent, [
        APP_ROUTER_PROVIDERS,
        HTTP_PROVIDERS,
        {provide: LocationStrategy, useClass: HashLocationStrategy}
    ]);
    
  • 91

    对于那些真正想要 PathLocationStrategy (即html5Mode)而不是 HashLocationStrategy 的人(比如我),请参阅第三方维基中的How to: Configure your server to work with html5Mode

    如果启用了html5Mode,则不会在您的网址中使用#字符 . #符号很有用,因为它不需要服务器端配置 . 没有#,URL看起来更好,但它也需要服务器端重写 .

    在这里我只复制wiki中的三个例子,以防Wiki丢失 . 通过搜索关键字"URL rewrite"(例如,适用于Firebase的this answer)可以找到其他示例 .

    Apache

    <VirtualHost *:80>
        ServerName my-app
    
        DocumentRoot /path/to/app
    
        <Directory /path/to/app>
            RewriteEngine on
    
            # Don't rewrite files or directories
            RewriteCond %{REQUEST_FILENAME} -f [OR]
            RewriteCond %{REQUEST_FILENAME} -d
            RewriteRule ^ - [L]
    
            # Rewrite everything else to index.html to allow HTML5 state links
            RewriteRule ^ index.html [L]
        </Directory>
    </VirtualHost>
    

    Documentation for rewrite module

    nginx

    server {
        server_name my-app;
    
        root /path/to/app;
    
        location / {
            try_files $uri $uri/ /index.html;
        }
    }
    

    Documentation for try_files

    IIS

    <system.webServer>
      <rewrite>
        <rules> 
          <rule name="Main Rule" 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>
    
  • 185

    如果您在Visual Studio 2015中通过ASP.NET Core 1运行Angular 2,您可能会发现JürgenGutsch的此解决方案很有帮助 . 他在a blog post描述了它 . 这对我来说是最好的解决方案 . 在app.UseStaticFiles()之前,将下面提供的C#代码放在Startup.cs public void Configure()中;

    app.Use( async ( context, next ) => {
        await next();
    
        if( context.Response.StatusCode == 404 && !Path.HasExtension( context.Request.Path.Value ) ) {
            context.Request.Path = "/index.html";
            await next();
        }
    });
    
  • 66

    我有同样的问题 . 我的Angular应用程序正在Windows服务器上运行 .

    我通过在 root 目录中创建 web.config 文件解决了这个问题 .

    <?xml version="1.0" encoding="UTF-8"?>
    <configuration>
      <system.webServer>
        <rewrite>
          <rules>
            <rule name="AngularJS" 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>
    
  • 4

    Angular 2最终版本的更新

    在app.module.ts中:

    • 添加进口:
    import { HashLocationStrategy, LocationStrategy } from '@angular/common';
    
    • 在NgModule提供程序中,添加:
    {provide: LocationStrategy, useClass: HashLocationStrategy}
    

    Example (app.module.ts):

    import { NgModule }       from '@angular/core';
    import { BrowserModule  } from '@angular/platform-browser';
    import { AppComponent }   from './app.component';
    import { HashLocationStrategy, LocationStrategy } from '@angular/common';
    
    @NgModule({
        declarations: [AppComponent],
        imports: [BrowserModule],
        providers: [{provide: LocationStrategy, useClass: HashLocationStrategy}],
        bootstrap: [AppComponent],
    })
    export class AppModule {}
    

    替代方案

    将RouterModule.forRoot与{useHash:true}参数一起使用 .

    Example: (来自angular docs

    import { NgModule } from '@angular/core';
    ...
    
    const routes: Routes = [//routes in here];
    
    @NgModule({
      imports: [
        BrowserModule,
        FormsModule,
        RouterModule.forRoot(routes, { useHash: true })
      ],
      bootstrap: [AppComponent]
    })
    export class AppModule { }
    
  • 19

    也许您可以在使用RouterModule注册根目录时执行此操作 . 您可以传递具有属性“useHash:true”的第二个对象,如下所示:

    import { NgModule }       from '@angular/core';
    import { BrowserModule  } from '@angular/platform-browser';
    import { AppComponent }   from './app.component';
    import { ROUTES }   from './app.routes';
    
    @NgModule({
        declarations: [AppComponent],
        imports: [BrowserModule],
        RouterModule.forRoot(ROUTES ,{ useHash: true }),],
        providers: [],
        bootstrap: [AppComponent],
    })
    export class AppModule {}
    
  • 14

    事实上,刷新应用程序时出现404错误是正常的,因为浏览器中的实际地址正在更新(并且没有#/ hashbang方法) . 默认情况下,HTML5历史记录用于在Angular2中重用 .

    要修复404错误,您需要更新服务器以为您定义的每个路径路径提供 index.html 文件 .

    如果要切换到HashBang方法,则需要使用此配置:

    import {bootstrap} from 'angular2/platform/browser';
    import {provide} from 'angular2/core';
    import {ROUTER_PROVIDERS} from 'angular2/router';
    import {LocationStrategy, HashLocationStrategy} from '@angular/common';
    
    import {MyApp} from './myapp';
    
    bootstrap(MyApp, [
      ROUTER_PROVIDERS,
      {provide: LocationStrategy, useClass: HashLocationStrategy}
    ]);
    

    在这种情况下,当您刷新页面时,它将再次显示(但您的地址中将包含 # ) .

    这个链接也可以帮到你:When I refresh my website I get a 404. This is with Angular2 and firebase .

    希望它对你有帮助,蒂埃里

相关问题