我已经将我的单页应用程序存储在我的服务器中一个名为“myapp”的文件夹中。我已经将base中的URL更改为http://example.com/myapp/ '。
我的项目有两页。所以我实现了Angular 2的路由。我将默认页面设置为login。当我在浏览器中输入http://example.com/myapp/时,它会自动重定向到http://example.com/myapp/login。但是如果刷新该页,我会得到一个404错误,表示没有找到http://example.com/myapp/login。
但是如果我使用lite服务器运行我的项目,一切都正常工作。在这种情况下,index.html中的基本URL将是“/”。怎么解决呢?
事实上,在刷新应用程序时出现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}
]);
在这种情况下,当您刷新页面时,它将再次显示(但您的地址中将有一个#)。
这个链接也可以帮助你:当我刷新我的网站时,我得到一个404。这是使用Angular2和firebase。
希望它能帮助到你,
亨利
对于使用Angular 2 rc4或更高版本的读者来说,LocationStrategy似乎已经从路由器移到了通用。你必须从那里导入。
还要注意“提供”行周围的花括号。
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}
]);
Angular 2最终版的更新
在app.module.ts:
增加进口:
import {HashLocationStrategy, LocationStrategy} from '@angular/common';
在NgModule提供程序中添加:
{提供:LocationStrategy, useClass: HashLocationStrategy}
例子(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。使用{useHash: true}参数的forRoot。
例子:(来自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 { }
也许你可以在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 {}
对于像我这样真正想要PathLocationStrategy(即html5Mode)而不是HashLocationStrategy的人,请参阅如何:配置您的服务器从第三方wiki使用html5Mode:
当你启用html5Mode时,#字符将不再在你的url中使用。符号#很有用,因为它不需要服务器端配置。如果没有#,URL看起来会更好,但也需要服务器端重写。
这里我只从维基上抄了三个例子,以防维基弄丢了。其他的例子可以通过搜索关键字“URL重写”找到(例如Firebase的这个答案)。
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>
重写模块的文档
恩金克斯
server {
server_name my-app;
root /path/to/app;
location / {
try_files $uri $uri/ /index.html;
}
}
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>