Angular 2.0路由器无法重新加载浏览器


189

我正在使用Angular 2.0.0-alpha.30版本。当重定向到其他路由时,请刷新浏览器,其显示无法获取/ route。

您能帮我弄清楚为什么会发生此错误。



感谢您的答复,但其中一个是针对1.x版本的。我在angular 2.0中面临这个问题。
Vinz和Tonz

1
链接的问题是pushState的一般问题,而不是特定于Angular的问题。您的问题没有提供足够的信息来知道是否相关。
君特Zöchbauer

5
Angular 2.0使用了全新的路由器,因此链接的帖子自从它是旧路由器以来就不再有用了
Vinz和Tonz

如我所说,如果是pushState问题,则它不是Angular特定的,不能由Angular修复,而是需要在服务器上修复。
君特Zöchbauer

Answers:


141

您看到的错误是因为您正在请求不存在的http:// localhost / route。据西蒙说

使用html5路由时,您需要将应用中的所有路由(当前为404)映射到服务器端的index.html。以下是一些适合您的选项:

  1. 使用实时服务器:https : //www.npmjs.com/package/live-server

    $live-server --entry-file=index.html`
    
  2. 使用Nginx:http//nginx.org/en/docs/beginners_guide.html

    error_page 404 /index.html
    
  3. Tomcat-web.xml的配置。从库宁的评论

    <error-page>
          <error-code>404</error-code>
          <location>/index.html</location>
    </error-page>
    

1
由于需要HTML5路由的服务器端支持,因此效果很好。Thanx
Prabhat

我可以使用nginx作为代理pub serve吗?这样,pub build在开发过程中我不需要太多。我曾尝试过,但proxy_pass不能很好地配合使用error_page
富兰克林于

@FranklinYu我以前没做过。你解决了吗?
Quy Tang

1
使用nginx。,应用位置中的error_page 404 /index.html对我有用。谢谢。
理查德·坎皮恩

2
Tomcat-web.xml的配置<error-page> <error-code> 404 </ error-code> <location> /index.html </ location> </ error-page>
Kunin

65

免责声明:此修复程序适用于Alpha44

我有同样的问题,并通过实施解决它HashLocationStrategy在Angular.io API预览上市。

https://angular.io/docs/ts/latest/api/common/index/HashLocationStrategy-class.html

首先导入必要的指令

import {provide} from 'angular2/angular2';
import {
  ROUTER_PROVIDERS,
  LocationStrategy,
  HashLocationStrategy
} from 'angular2/router';

最后,像这样自举

bootstrap(AppCmp, [
  ROUTER_PROVIDERS,
  provide(LocationStrategy, {useClass: HashLocationStrategy})
]);

您的路由将显示为http:// localhost /#/ route,刷新后将在适当的位置重新加载。

希望有帮助!


1
这段代码可以正常工作,但是使用此技术#会自动在URL中添加此技术中的一些问题。有什么解决方案可以使用此方法从URL中删除#吗?
Pardeep Jain

同意,我尝试实现此处列出的“ PathLocationStrategy” ,但无法使其正常工作。没有的网址#将是最佳选择。
SimonHawesome

是的,我也尝试了与相同的操作,PathLocationStrategy但这对我不起作用。我使用了错误的方法,或者我不知道如何使用PathLocationStrategy。
Pardeep Jain

1
在RC1中,这对我不起作用。从'@ angular / router'导入LocationStrategy和HashLocationStrategy失败。
infojolt

1
抱歉,超过1年后再次提出此问题:)但是HashLocationStrategy是否有助于保持在同一路由器路径上?就我而言,当我刷新时,它将带我到localhost /#/ <default route>,即主页的默认路由。当我“刷新”时,我该如何转到当前的原路线?
rajugaadu

47

默认情况下PathLocationStrategy,Angular 使用HTML5 pushstate(在Angular lang语中)。
您或者需要一个服务器来处理所有正在请求的请求,index.html或者切换到https://angular.io/docs/ts/latest/api/common/index/HashLocationStrategy-classHashLocationStrategy(在路由的URL中使用#)。 html

另请参见https://ngmilk.rocks/2015/03/09/angularjs-html5-mode-or-pretty-urls-on-apache-using-htaccess/

切换HashLocationStrategy使用

> = RC.5和2.0.0 final的更新

import {HashLocationStrategy, LocationStrategy} from '@angular/common';

@NgModule({
  declarations: [AppCmp], 
  bootstrap: [AppCmp],
  imports: [BrowserModule, routes],
  providers: [{provide: LocationStrategy, useClass: HashLocationStrategy}]
]);

或更短 useHash

imports: [RouterModule.forRoot(ROUTER_CONFIG, {useHash: true}), ...

确保您拥有所有必需的进口

对于新的(RC.3)路由器

<base href="."> 

也可能导致404。

它需要代替

<base href="/">

> = RC.x更新

bootstrap(AppCmp, [
  ROUTER_PROVIDERS,
  provide(LocationStrategy, {useClass: HashLocationStrategy})
  // or since RC.2
  {provide: LocationStrategy, useClass: HashLocationStrategy} 
]);

import {provide} from '@angular/core';
import {  
  PlatformLocation,  
  Location,  
  LocationStrategy,  
  HashLocationStrategy,  
  PathLocationStrategy,  
  APP_BASE_HREF}  
from '@angular/common';  

更新为> = beta.16进口已经改变

import {BrowserPlatformLocation} from '@angular/platform-browser';

import {provide} from 'angular2/core';
import {
  // PlatformLocation,
  // Location,
  LocationStrategy,
  HashLocationStrategy,
  // PathLocationStrategy,
  APP_BASE_HREF}
from 'angular2/router';
import {BrowserPlatformLocation} from 'angular2/src/router/location/browser_platform_location';

<beta 16

import {provide} from 'angular2/core';
import {
  HashLocationStrategy
  LocationStrategy,
  ROUTER_PROVIDERS,
} from 'angular2/router';

另请参见https://github.com/angular/angular/blob/master/CHANGELOG.md#200-beta16-2016-04-26重大更改


1
谢谢!提供似乎已移至“角度/核心”下:从“角度2 /核心”导入{provide}
StrangeLoop

1
请注意:update for >= RC.x(RC.2)与一起使用router 3.0.0-alpha.7,但是provide注释为不推荐使用,而没有有关哪个函数替换了它的信息。
2016年

使用{provide: SomeClass, useClass: OtherClass}
君特Zöchbauer

2
最新答案。对于最新版本的angular 2.4.1,我有<base href =“ ./”>。更改为<base href =“ /”>可以解决我遇到的问题。可能对某人有帮助。
撒耶夫·法鲁克

28

我认为您看到的错误是因为您正在请求不存在的http:// localhost / route。您需要确保服务器将所有请求映射到您的主index.html页面。

由于Angular 2默认使用html5路由,而不是在URL末尾使用哈希,因此刷新页面看起来就像是对其他资源的请求。


7
那么我们该如何解决呢?默认情况下,我们如何将所有请求映射到主索引?它依赖服务器吗?
Ayyash

1
是的,您将在服务器上使用任何正在使用的Web框架执行此操作。另一种方法是使用HashLocationStrategy,如下所述。
西蒙

您将在每个不存在的路线中重新加载角度SPA。它应该如何处理?
加里

仅当用户单击浏览器上的刷新时才重新加载,而不是当用户通过UI更改路由时重新加载。用户刷新时,重装实际上并没有任何办法。
华莱士·霍瑞

19

如果您使用默认的HTML位置策略,则在所有路由器版本中都是这种情况。

发生的情况是,浏览器栏上的URL是普通的完整HTML URL,例如:http://localhost/route

因此,当我们在浏览器栏中单击Enter时,实际的HTTP请求已发送到服务器以获取名为的文件route

服务器没有这样的文件,并且在服务器上也没有配置express之类的东西来处理请求并提供响应,因此服务器返回404 Not Found,因为找不到route文件。

我们希望服务器返回index.html包含单页应用程序的文件。然后,路由器应插入并处理该/routeURL,并显示映射到它的组件。

因此,要解决此问题,我们需要将服务器配置为index.html在无法处理请求的情况下返回(假设是您的单页应用程序文件的名称),而不是“ 404未找到”。

执行此操作的方式将取决于所使用的服务器端技术。例如,如果您的Java是Java,则可能需要编写servlet,而在Rails中,它将有所不同,依此类推。

举一个具体的例子,例如,如果您使用的是NodeJ,则必须编写这样的中间件:

function sendSpaFileIfUnmatched(req,res) {
    res.sendFile("index.html", { root: '.' });
}

然后在中间件链的最后注册它:

app.use(sendSpaFileIfUnmatched);

这将index.html代替返回404,而不是返回404,路由器将启动,一切将按预期工作。


这正是我的问题。如果您使用NGINX,这个答案可以帮助解决这个问题:stackoverflow.com/questions/7027636/...
内森

是否有关于如何针对Java执行此操作的教程?谢谢。
000000000000000000000

13

确保将其放置在index.html的head元素中:

<base href="https://stackoverflow.com/">

Angular2 Routing&Navigation文档中的示例在开头改用了以下代码(它们在文档的实时示例注释中解释了原因):

<script>document.write('<base href="' + document.location + '" />');</script>

刷新页面时,这将动态将基本href设置为当前document.location。我可以看到这引起了人们对文档的略读并试图复制该插件的困惑。


感谢您分享。让我们清楚一点,只有当我在将所有css加载到<head>之后,并且在加载任何Js文件之前,直接将<base href =“ /”>放在<base href =“ /”>中时,它才对我有用。我希望它对任何人
都有

我在index.html中具有<base href =“ ./”>,然后将其删除。从href和它的工作..
Saurabh Solanki

10

如果您希望能够在浏览器中输入URL而不配置AppServer来处理对index.html的所有请求,则必须使用HashLocationStrategy

最简单的配置方法是使用:

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

代替:

RouterModule.forRoot(routes)

随着HashLocationStrategy您的网址会像:

http://server:port/#/path

谢谢!这会有所帮助,但是我不想#从url中删除,可以删除吗?
Hidayt Rahman '18

7

我在使用webpack-dev-server时遇到了同样的问题。我必须将devServer选项添加到我的webpack中。

解:

// in webpack
devServer: {
    historyApiFallback: true,
    stats: 'minimal'
}

巫毒的种类:p有关更多信息,请参见:webpack.github.io/docs/…–
Jissay

7

如果您使用Apache或Nginx作为服务器,则必须创建一个.htaccess(如果之前未创建)和“开” RewriteEngine

RewriteEngine On  
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteRule ^ - [L]
RewriteRule ^ /index.html

没收到您的问题,此方法已在Apache和Nginx(nginx.com)服务器上进行了测试
Rakesh Roy

1
这仅适用于Apache。Nginx的配置格式完全不同。
富兰克林于

5

我的服务器是Apache,刷新或深层链接时修复404的工作非常简单。只需在apache vhost配置中添加一行:

ErrorDocument 404 /index.html

这样任何404错误都将重定向到index.html,这是angular2路由所需要的。

整个虚拟主机文件示例:

<VirtualHost *:80>
  ServerName fenz.niwa.local
  DirectoryIndex index.html
  ErrorDocument 404 /index.html

  DocumentRoot "/Users/zhoum/Documents/workspace/fire/fire_service/dist"
  ErrorLog /Users/zhoum/Documents/workspace/fire/fire_service/logs/fenz.error.log
  CustomLog /Users/zhoum/Documents/workspace/fire/fire_service/logs/fenz.access.log combined

  <Directory "/Users/zhoum/Documents/workspace/fire/fire_service/dist">
    AllowOverride All
    Options Indexes FollowSymLinks
    #Order allow,deny
    #Allow from All
    Require all granted
  </Directory>

  Header set Access-Control-Allow-Origin "*"
  Header set Access-Control-Allow-Methods "GET, POST"
  Header set Access-Control-Allow-Credentials "true"
  Header set Access-Control-Allow-Headers "Accept-Encoding"
</VirtualHost>

无论您使用的是哪种服务器,我都认为要找出要配置服务器以将404重定向到index.html的方法。


4

服务器配置不是SPA的解决方案,我什至认为。如果您输入错误的路线,您不想再次重新加载有角度的SPA,是吗?因此,我不会依赖服务器路由并重定向到其他路由,但是是的,我将让index.html处理对角度应用程序路径的角度路由的所有请求。

尝试此操作,而不要使用其他方法或错误的路线。它对我有用,不确定,但似乎正在进行中。遇到问题时,我自己迷失了方向。

@RouteConfig([
  { path: '/**', redirectTo: ['MycmpnameCmp'] }, 
   ...
  }
])

https://github.com/angular/angular/issues/4055

但是,请记住配置服务器文件夹和访问权限,以防您拥有非SPA的HTML或Web脚本。否则,您将面临问题。对我来说,遇到像您这样的问题时,这是服务器配置和以上配置的混合。


4

对于角度5快速修复,请编辑app.module.ts{useHash:true}在appRoutes之后添加。

@NgModule(
{
  imports:[RouterModule.forRoot(appRoutes,{useHash:true})]
})

3

Angular应用程序非常适合与简单的静态HTML服务器一起使用。您不需要服务器端引擎来动态编写应用程序页面,因为Angular在客户端进行此操作。

如果应用程序使用Angular路由器,则必须将服务器配置为在系统询问应用程序没有的文件时返回应用程序的宿主页(index.html)。

路由的应用程序应支持“深层链接”。深层链接是一个URL,用于指定应用程序内部组件的路径。例如,http://www.example.com/heroes/42是指向英雄详细信息页面的深层链接,该页面显示ID为42的英雄。

当用户从正在运行的客户端中导航到该URL时没有问题。Angular路由器解释URL并路由到该页面和英雄。

但是,单击电子邮件中的链接,在浏览器地址栏中输入链接,或仅在英雄详细信息页面上刷新浏览器-所有这些操作均由浏览器本身在运行的应用程序外部进行处理。浏览器绕过路由器直接向服务器请求该URL。

静态服务器在收到http://www.example.com/的请求时,通常会返回index.html 。但是它会拒绝http://www.example.com/heroes/42并返回404-Not Found错误,除非配置为返回index.html为止

如果在生产中发生此问题,请按照以下步骤操作

1)在angular应用程序的src文件夹中添加一个Web.Config文件。将下面的代码放在其中。

<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="/" />
    </rule>
    </rules>
</rewrite>
</system.webServer>
</configuration>

2)在angular-cli.json中添加对其的引用。在angular-cli.json中,将Web.config放在资产块中,如下所示。

"assets": [
    "assets",
    "favicon.ico",
    "Web.config"
  ],

3)现在您可以使用以下方法构建用于生产的解决方案

ng build --prod

这将创建一个dist文件夹。dist文件夹中的文件可通过任何方式部署。


最佳解决方案,可以从以下角度找到详细信息:angular.io/guide/deployment#fallback在创建web.config文件时,不要忘记添加<configuration> </ configuration>标记。感谢您的回答Malatesh。
Palash Roy

3

您可以将此解决方案用于一般应用程序,我使用ejs作为视图引擎:

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.engine('html', require('ejs').renderFile);
app.use(function (req, res, next) {
    return res.render('index.html');
});

并在angular-cli.json中设置

"apps": [
    {
      "root": "src",
      "outDir": "views",

它会正常工作,而不是

app.get('*', function (req, res, next) {
    res.sendFile('dist/index.html', { root: __dirname });
 });

它与get db调用并返回index.html的创建问题


1
对于MEAN堆栈应用程序,此功能在2017年10月完美运行。
Mindsect队

2

对于我们这些在生活中挣扎IIS:使用下面的PowerShell代码来解决根据官方公布的角2个文档这个问题(有人张贴在这个线程?http://blog.angular-university.io/angular2-router/

Import-WebAdministration
# Grab the 404 handler and update it to redirect to index.html.
$redirect = Get-WebConfiguration -filter "/system.WebServer/httperrors/error[@statusCode='404']" -PSPath IIS:\Sites\LIS 
$redirect.path = "/index.html"
$redirect.responseMode = 1
# shove the updated config back into IIS
Set-WebConfiguration -filter "/system.WebServer/httperrors/error[@statusCode='404']" -PSPath IIS:\Sites\LIS -value $redirect

根据Angular 2文档(上面的链接)中的建议,这会将404重定向到/index.html文件。


2

您可以在下面尝试。这个对我有用!

main.component.ts

import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';

...
export class MainComponent implements OnInit {
    constructor(private router: Router) {
        let path: string = window.location.hash;
        if (path && path.length > 0) {
            this.router.navigate([path.substr(2)]);
        }
    }

    public ngOnInit() { }
}

您可以进一步增强path.substr(2)以拆分为路由器参数。我正在使用角度2.4.9


这对于处理浏览器刷新非常有帮助!对于角度5,我必须对其进行一些修改以使用window.location.pathname,并将该值与预期路径进行比较。
华莱士·霍瑞

2

我只是在根目录中添加.htaccess。

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
    RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
    RewriteRule ^ - [L]
    RewriteRule ^ ./index.html
</IfModule>

在这里,我只是将/index.html中的点'。'(父目录)添加到./index.html中,
确保基本路径中的index.html文件是主目录路径并在项目的构建中进行设置。


1

我想在HTML5模式下保留子页面的URL路径,而无需重定向回索引,那里没有任何解决方案告诉我如何执行此操作,因此这是我的实现方式:

在IIS中为所有路由创建简单的虚拟目录,并将它们指向应用程序根目录。

使用以下位置标记将system.webServer包裹在Web.config.xml中,否则,您将从虚拟目录中再次加载Web.config时得到重复的错误:

<configuration>
    <location path="." inheritInChildApplications="false">
    <system.webServer>
        <defaultDocument enabled="true">
            <files>
                <add value="index.html" />
            </files>
        </defaultDocument>
    </system.webServer>
  </location>
</configuration>


1

如果要使用PathLocationStrategy:

  • Wildfly配置:
    • 创建undertow-handlers.conf文件以放置在WEB-INF中
    • 内容:(不包括其他端点!)
      • regex ['(../ overview / ?.?$)']而非regex ['(.. endpoints)']-> rewrite ['/ index.html']
      • regex ['(.. deployments / ?.?$)']而不是regex ['(.. endpoints)']-> rewrite ['/ index.html']

具有Java EE / Wildfly的单页应用程序:服务器端配置


1

2017年七月,11:由于这是链接从有这个问题,但采用了棱角分明2电子的一个问题,我会在这里我的解决方案。

我要做的就是<base href="./">从index.html 中删除,Electron再次开始成功重新加载页面。


1

添加进口:

import { HashLocationStrategy, LocationStrategy } from '@angular/common';

在NgModule提供程序中,添加:

providers: [{provide: LocationStrategy, useClass: HashLocationStrategy}]

在应用程序的主index.html文件中,将基本href更改为./index.htmlfrom/

部署在任何服务器上的应用程序将提供可从任何外部应用程序访问的页面的真实URL。


1

只需在根目录解析中添加.htaccess 404即可,同时刷新角度为4的apache2中的页面。

<IfModule mod_rewrite.c>
    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]
</IfModule>

1

我认为您正在获取404,因为您正在请求http:// localhost / route,而该服务器在tomcat服务器上不存在。由于Angular 2默认使用html 5路由,而不是在URL末尾使用哈希,因此刷新页面看起来就像是对其他资源的请求。

在tomcat上使用角度路由时,您需要确保服务器在刷新页面时将应用中的所有路由映射到您的主index.html。有多种方法可以解决此问题。无论哪种适合您,您都可以这样做。

1)将以下代码放在部署文件夹的web.xml中:

<error-page>
     <error-code>404</error-code>
     <location>/index.html</location>
</error-page>

2)您也可以尝试将HashLocationStrategy与路由的URL中的#一起使用:

尝试使用:

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

代替:

RouterModule.forRoot(routes)

使用HashLocationStrategy,您的网址将类似于:

http:// localhost /#/ route

3)Tomcat URL重写阀:如果找不到资源,则使用服务器级别的配置重写URL以重定向到index.html。

3.1)在META-INF文件夹中,创建一个文件context.xml并在其中复制以下上下文。

<? xml version='1.0' encoding='utf-8'?>
<Context>
  <Valve className="org.apache.catalina.valves.rewrite.RewriteValve" />
</Context>

3.2)在WEB-INF内,创建文件rewrite.config(此文件包含URL重写规则,tomcat用于URL重写)。在rewrite.config中,复制以下内容:

  RewriteCond %{SERVLET_PATH} !-f
  RewriteRule ^/(.*)$ /index.html [L]

0

这不是正确的答案,但是在刷新时,您可以通过牺牲404页面将所有无效呼叫重定向到首页,这是一个临时破解,只需在404.html文件上重播

<!doctype html>
<html>
    <head>
        <script type="text/javascript">
            window.location.href = "http://" + document.location.host;
        </script>
    </head>
</html>

0

解决“浏览器无法重新加载浏览器的路由器”的最佳解决方案是,我们应该使用spa-fallback。如果您使用的是带有asp.net核心的angular2应用程序,那么我们需要在“ StartUp.cs”页面上对其进行定义。在MVC溃败之下。我正在附上代码。

 app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");
            routes.MapSpaFallbackRoute("spa-fallback", new { controller = "Home", action = "Index" });
        });

0

答案很棘手。如果使用普通的旧Apache服务器(或IIS),则会出现问题,因为Angular页面不存在。它们是从Angular路线“计算”而来的。

有几种方法可以解决此问题。一种是使用Angular提供的HashLocationStrategy。但是,URL中添加了一个尖锐的符号。这主要是为了与Angular 1(我假设)兼容。事实是Sharp后面的部分不是URL的一部分(然后服务器解析“#”符号前面的部分)。那可能是完美的。

这里是增强的方法(基于404技巧)。我假设您具有角度应用程序的“分布式”版本(ng build --prod如果您使用Angular-CLI),并且您可以直接通过服务器访问页面并启用PHP。

如果您的网站是基于页面的(例如Wordpress),并且您只有一个专用于Angular的文件夹(在我的示例中名为“ dist”),您可以做一些奇怪的事情,但最后却很简单。我假设您已将Angular页面存储在“ / dist”中(与一起使用<BASE HREF="/dist/">)。现在使用404重定向和PHP的帮助。

在您的Apache配置中(或在.htaccessangular应用程序目录的文件中),您必须添加ErrorDocument 404 /404.php

404.php将以以下代码开头:

<?php
$angular='/dist/';
if( substr($_SERVER['REQUEST_URI'], 0, strlen($angular)) == $angular ){
    $index = $_SERVER['DOCUMENT_ROOT'] . $angular . "index.html";
    http_response_code(200);
    include $index;
    die;
}

// NOT ANGULAR...
echo "<h1>Not found.</h1>"

$angular存储在您的angular的HREF中的值在哪里index.html

原理很简单,如果Apache找不到页面,则会对PHP脚本进行404重定向。我们只是检查页面是否在角度应用程序目录内。如果是这种情况,我们只需直接加载index.html(无需重定向):这是保持URL不变的必要条件。我们还将HTTP代码从404更改为200(对于爬虫来说更好)。

如果角度应用程序中不存在该页面怎么办?好吧,我们使用角度路由器的“全部捕获”功能(请参阅Angular路由器文档)。

此方法可与基本网站内的嵌入式Angular应用程序一起使用(我认为将来会如此)。

笔记:

  • 尝试mod_redirect通过重写URL 来完成此操作根本不是一个好的解决方案,因为必须真正加载文件(如资产),这比仅使用“未找到”解决方案具有更大的风险。
  • 只是使用Works进行重定向,ErrorDocument 404 /dist/index.html但Apache仍然会响应404错误代码(这对爬虫不利)。

0

这不是解决该问题的永久方法,而更像是一种解决方法或hack

将我的Angular应用程序部署到gh页时,我遇到了同样的问题。首先,当我在gh-pages上刷新页面时,收到404条消息。

然后正如@gunter指出的那样,我开始使用HashLocationStrategyAngular 2提供的功能。

但这带来了它自己的一系列问题#,而url中的内容确实很糟糕,使url看起来像这样https://rahulrsingh09.github.io/AngularConcepts/#/faq

我开始研究此问题,并遇到了一个博客。我试了一下,它奏效了。

这就是我在该博客中提到的内容。

首先,您需要在gh-pages仓库中添加一个404.html文件,该文件中包含一个空的HTML文档-但您的文档总数必须超过512个字节(如下所述)。接下来,在您的404.html页面的head元素中添加以下标记:

<script>
  sessionStorage.redirect = location.href;
</script>
<meta http-equiv="refresh" content="0;URL='/REPO_NAME_HERE'"></meta>

此代码将尝试的入口URL设置为标准sessionStorage对象上的变量,并使用元刷新标记立即将其重定向到您项目的index.html页面。如果您正在使用Github Organization网站,则不要在内容属性替换文本中输入存储库名称,只需执行以下操作:content =“ 0; URL ='/'”

为了捕获和还原用户最初导航到的URL,您需要在index.html页面的开头添加以下脚本标签,然后其他JavaScript才会作用于该页面的当前状态:

<script>
  (function(){
    var redirect = sessionStorage.redirect;
    delete sessionStorage.redirect;
    if (redirect && redirect != location.href) {
      history.replaceState(null, null, redirect);
    }
  })();
</script>

这一段JavaScript会检索我们在404.html页上的sessionStorage中缓存的URL,并用它替换当前的历史记录条目。

参考backalleycoder感谢@Daniel提供此解决方法。

现在上述URL更改为https://rahulrsingh09.github.io/AngularConcepts/faq


0

我通过添加一个与Angular路由中定义的所有内容匹配的处理程序(使用Java / Spring后端)来解决此问题,该处理程序将发回index.html而不是404。这将有效地(重新)引导应用程序并加载正确的页面。我也有一个404处理程序,可以处理所有未被此处理程序捕获的事件。

@Controller         ////don't use RestController or it will just send back the string "index.html"
public class Redirect {

    private static final Logger logger = LoggerFactory.getLogger(Redirect.class);

    @RequestMapping(value = {"comma", "sep", "list", "of", "routes"})
    public String redirectToIndex(HttpServletRequest request) {
        logger.warn("Redirect api called for URL {}. Sending index.html back instead. This will happen on a page refresh or reload when the page is on an Angular route", request.getRequestURL());
        return "/index.html";
    }
}

0

如果将Apache或Nginx用作服务器,则需要创建.htaccess

<IfModule mime_module>
      AddHandler application/x-httpd-ea-php72 .php .php7 .phtml
    </IfModule>
    # php -- END cPanel-generated handler, do not edit

    <IfModule mod_rewrite.c>
        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]
    </IfModule>
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.