我正在使用Angular 2.0.0-alpha.30版本。当重定向到其他路由时,请刷新浏览器,其显示无法获取/ route。
您能帮我弄清楚为什么会发生此错误。
我正在使用Angular 2.0.0-alpha.30版本。当重定向到其他路由时,请刷新浏览器,其显示无法获取/ route。
您能帮我弄清楚为什么会发生此错误。
Answers:
您看到的错误是因为您正在请求不存在的http:// localhost / route。据西蒙说。
使用html5路由时,您需要将应用中的所有路由(当前为404)映射到服务器端的index.html。以下是一些适合您的选项:
使用实时服务器:https : //www.npmjs.com/package/live-server
$live-server --entry-file=index.html`
使用Nginx:http://nginx.org/en/docs/beginners_guide.html
error_page 404 /index.html
Tomcat-web.xml的配置。从库宁的评论
<error-page>
<error-code>404</error-code>
<location>/index.html</location>
</error-page>
免责声明:此修复程序适用于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,刷新后将在适当的位置重新加载。
希望有帮助!
#
会自动在URL中添加此技术中的一些问题。有什么解决方案可以使用此方法从URL中删除#吗?
#
将是最佳选择。
PathLocationStrategy
但这对我不起作用。我使用了错误的方法,或者我不知道如何使用PathLocationStrategy。
默认情况下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重大更改
update for >= RC.x
(RC.2)与一起使用router 3.0.0-alpha.7
,但是provide
注释为不推荐使用,而没有有关哪个函数替换了它的信息。
{provide: SomeClass, useClass: OtherClass}
我认为您看到的错误是因为您正在请求不存在的http:// localhost / route。您需要确保服务器将所有请求映射到您的主index.html页面。
由于Angular 2默认使用html5路由,而不是在URL末尾使用哈希,因此刷新页面看起来就像是对其他资源的请求。
如果您使用默认的HTML位置策略,则在所有路由器版本中都是这种情况。
发生的情况是,浏览器栏上的URL是普通的完整HTML URL,例如:http://localhost/route
。
因此,当我们在浏览器栏中单击Enter时,实际的HTTP请求已发送到服务器以获取名为的文件route
。
服务器没有这样的文件,并且在服务器上也没有配置express之类的东西来处理请求并提供响应,因此服务器返回404 Not Found,因为找不到route
文件。
我们希望服务器返回index.html
包含单页应用程序的文件。然后,路由器应插入并处理该/route
URL,并显示映射到它的组件。
因此,要解决此问题,我们需要将服务器配置为index.html
在无法处理请求的情况下返回(假设是您的单页应用程序文件的名称),而不是“ 404未找到”。
执行此操作的方式将取决于所使用的服务器端技术。例如,如果您的Java是Java,则可能需要编写servlet,而在Rails中,它将有所不同,依此类推。
举一个具体的例子,例如,如果您使用的是NodeJ,则必须编写这样的中间件:
function sendSpaFileIfUnmatched(req,res) {
res.sendFile("index.html", { root: '.' });
}
然后在中间件链的最后注册它:
app.use(sendSpaFileIfUnmatched);
这将index.html
代替返回404,而不是返回404,路由器将启动,一切将按预期工作。
确保将其放置在index.html的head元素中:
<base href="https://stackoverflow.com/">
Angular2 Routing&Navigation文档中的示例在开头改用了以下代码(它们在文档的实时示例注释中解释了原因):
<script>document.write('<base href="' + document.location + '" />');</script>
刷新页面时,这将动态将基本href设置为当前document.location。我可以看到这引起了人们对文档的略读并试图复制该插件的困惑。
如果您希望能够在浏览器中输入URL而不配置AppServer来处理对index.html的所有请求,则必须使用HashLocationStrategy。
最简单的配置方法是使用:
RouterModule.forRoot(routes, { useHash: true })
代替:
RouterModule.forRoot(routes)
随着HashLocationStrategy您的网址会像:
http://server:port/#/path
#
从url中删除,可以删除吗?
我在使用webpack-dev-server时遇到了同样的问题。我必须将devServer选项添加到我的webpack中。
// in webpack
devServer: {
historyApiFallback: true,
stats: 'minimal'
}
如果您使用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,刷新或深层链接时修复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的方法。
服务器配置不是SPA的解决方案,我什至认为。如果您输入错误的路线,您不想再次重新加载有角度的SPA,是吗?因此,我不会依赖服务器路由并重定向到其他路由,但是是的,我将让index.html处理对角度应用程序路径的角度路由的所有请求。
尝试此操作,而不要使用其他方法或错误的路线。它对我有用,不确定,但似乎正在进行中。遇到问题时,我自己迷失了方向。
@RouteConfig([
{ path: '/**', redirectTo: ['MycmpnameCmp'] },
...
}
])
https://github.com/angular/angular/issues/4055
但是,请记住配置服务器文件夹和访问权限,以防您拥有非SPA的HTML或Web脚本。否则,您将面临问题。对我来说,遇到像您这样的问题时,这是服务器配置和以上配置的混合。
对于角度5快速修复,请编辑app.module.ts并{useHash:true}
在appRoutes之后添加。
@NgModule(
{
imports:[RouterModule.forRoot(appRoutes,{useHash:true})]
})
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文件夹中的文件可通过任何方式部署。
您可以将此解决方案用于一般应用程序,我使用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的创建问题
对于我们这些在生活中挣扎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文件。
您可以在下面尝试。这个对我有用!
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
我只是在根目录中添加.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文件是主目录路径并在项目的构建中进行设置。
我想在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>
如果要使用PathLocationStrategy:
添加进口:
import { HashLocationStrategy, LocationStrategy } from '@angular/common';
在NgModule提供程序中,添加:
providers: [{provide: LocationStrategy, useClass: HashLocationStrategy}]
在应用程序的主index.html文件中,将基本href更改为./index.html
from/
部署在任何服务器上的应用程序将提供可从任何外部应用程序访问的页面的真实URL。
只需在根目录解析中添加.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>
我认为您正在获取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,您的网址将类似于:
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]
解决“浏览器无法重新加载浏览器的路由器”的最佳解决方案是,我们应该使用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" });
});
答案很棘手。如果使用普通的旧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配置中(或在.htaccess
angular应用程序目录的文件中),您必须添加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 来完成此操作根本不是一个好的解决方案,因为必须真正加载文件(如资产),这比仅使用“未找到”解决方案具有更大的风险。ErrorDocument 404 /dist/index.html
但Apache仍然会响应404错误代码(这对爬虫不利)。这不是解决该问题的永久方法,而更像是一种解决方法或hack
将我的Angular应用程序部署到gh页时,我遇到了同样的问题。首先,当我在gh-pages上刷新页面时,收到404条消息。
然后正如@gunter指出的那样,我开始使用HashLocationStrategy
Angular 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
我通过添加一个与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";
}
}
如果将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>