Angular 2.0.0-alpha.30バージョンを使用しています。別のルートにリダイレクトするときは、ブラウザを更新してください。
なぜこのエラーが起きたのかを理解するのを手伝ってください。
あなたが見ているエラーは、あなたが http:// localhost/route を要求しているからです。によると サイモン 。
Html5ルーティングを使用するとき、あなたはあなたのサーバー側のindex.htmlにあなたのアプリ(現在404)の中のすべてのルートをマッピングする必要があります。ここにあなたのためのいくつかのオプションがあります:
ライブサーバーを使用して: 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の設定 Kunin さんのコメントから
<error-page> <error-code>404</error-code> <location>/index.html</location> </error-page>
免責事項:この修正はAlpha44で動作します。
私は同じ問題を抱えていて、Angular.io APIプレビューにリストされているHashLocationStrategyを実装することによってそれを解決しました。
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 のように表示され、更新するとそれは適切な場所にリロードされます。
それが役立つことを願っています!
私はあなたが見ているエラーはあなたが http:// localhost/route を要求しているので存在しないためだと思います。サーバーがすべての要求をメインのindex.htmlページにマップするようにする必要があります。
Angular 2は、URLの最後にハッシュを使用するのではなく、デフォルトでhtml5ルーティングを使用するため、ページを更新すると別のリソースを要求するように見えます。
デフォルトのHTMLロケーション戦略を使用している場合、これはすべてのルーターバージョンで共通の状況です。
何が起こるかというと、ブラウザバーのURLは通常の完全なHTMLのURLで、例えばhttp://localhost/route
です。
そのため、ブラウザバーでEnterキーを押すと、実際のHTTPリクエストがサーバーに送信され、route
という名前のファイルが取得されます。
サーバーにそのようなファイルがなく、サーバー上でexpressを処理して応答を提供するように設定されていないため、route
ファイルが見つからなかったため、サーバーは404 Not Foundを返します。
私たちが欲しいのは、サーバーが単一ページのアプリケーションを含むindex.html
ファイルを返すことです。それからルーターは/route
urlを起動して処理し、それにマップされているコンポーネントを表示します。
そのため、この問題を解決するには、404 Not Foundではなく、リクエストを処理できない場合にindex.html
を返すようにサーバーを設定する必要があります(これが単一ページのアプリケーションファイルの名前であると仮定します)。
これを行う方法は、使用されているサーバー側のテクノロジによって異なります。例えば、そのJavaがサーブレットを書かなければならない場合、Railsではそれは違うでしょう、など。
具体的な例を挙げると、たとえばNodeJを使用している場合は、次のようなミドルウェアを作成する必要があります。
function sendSpaFileIfUnmatched(req,res) {
res.sendFile("index.html", { root: '.' });
}
そしてミドルウェアチェーンの最後に登録します。
app.use(sendSpaFileIfUnmatched);
これは404を返す代わりにindex.html
を提供し、ルーターは起動し、すべてが期待通りに動作します。
これがあなたのindex.htmlのhead要素にあることを確認してください:
<base href="/">
Angular 2 Routing&Navigation のドキュメントの 例 では、次のコードを使用しています。その代わりに頭(ドキュメントの実際のサンプルノートでその理由を説明しています):
<script>document.write('<base href="' + document.location + '" />');</script>
ページを更新すると、これはベースのhrefを現在のdocument.locationに動的に設定します。これは、ドキュメントを読み飛ばしてplunkerを複製しようとしている人々に混乱を引き起こすことがわかりました。
サーバとしてApacheまたはNginxを使用している場合は、htaccess(以前に作成されていない場合)および "On"のRewriteEngineを作成する必要があります。
RewriteEngine On RewriteCond%{DOCUMENT_ROOT}%{REQUEST_URI} -f [または] RewriteCond%{DOCUMENT_ROOT}%{REQUEST_URI} -d RewriteRule ^ - [L] RewriteRule ^ /index.html
Webpack-dev-serverを使っても同じ問題がありました。私のWebパックにdevServerオプションを追加しなければなりませんでした。
// in webpack
devServer: {
historyApiFallback: true,
stats: 'minimal'
}
Index.htmlに対するすべての要求を処理するようにAppServerを設定せずにブラウザにURLを入力できるようにするには、HashLocationStrategyを使用する必要があります。
設定する最も簡単な方法は以下を使うことです。
RouterModule.forRoot(routes, { useHash: true })
の代わりに:
RouterModule.forRoot(routes)
HashLocationStrategyを使用すると、URLは次のようになります。
http://server:port/#/path
私のサーバーはApacheです。リフレッシュやディープリンクの際に404を修正するためにしたことはとても簡単です。 Apache vhost設定に1行追加するだけです。
ErrorDocument 404 /index.html
そのため、404エラーがあればindex.htmlにリダイレクトされます。
全体のバーチャルホストファイルの例:
<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にAngular App PathのAngularルートに対するすべてのリクエストを処理させます。
それ以外の場合や間違った経路の代わりにこれを試してください。確かではありませんが、進行中の作業のようです。問題に直面したときに私自身これをつまずいた。
@RouteConfig([
{ path: '/**', redirectTo: ['MycmpnameCmp'] },
...
}
])
https://github.com/angular/angular/issues/4055
ただし、SPA以外のHTMLまたはWebスクリプトがある場合は、サーバーフォルダとアクセス権を必ず設定してください。そうでなければあなたは問題に直面するでしょう。私にとってあなたのような問題に直面したとき、それはサーバー構成とそれ以上の混在でした。
あなたは平均的なアプリケーションのためにこの解決策を使うことができます、私はビューエンジンとして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の返却に関する問題
angular 5のクイック修正の場合は、app.module.tsを編集し、appRoutesの後に{useHash:true}
を追加します。
@NgModule(
{
imports:[RouterModule.forRoot(appRoutes,{useHash:true})]
})
IISでの生活を通して苦労している私たちのために:公式のAngular 2 docsに基づいてこの問題を解決するために以下のPowerShellコードを使用してください(誰かがこのスレッドに投稿しましたか? 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 docs(上記のリンク)の提案に従って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を使用しています
私はindexに戻ることなくHTML5モードでサブページのURLパスを保存したいと思っていました、そしてそこにある解決策のどれもこれを行う方法を教えてくれなかったので、これが私がそれを達成した方法です:
すべてのルートに対してIISに単純な仮想ディレクトリを作成し、それらをアプリのルートを指すようにします。
System.webServerをこのlocationタグでWeb.config.xmlにラップします。そうしないと、仮想ディレクトリで2回目にWeb.configをロードしたときに重複したエラーが発生します。
<configuration>
<location path="." inheritInChildApplications="false">
<system.webServer>
<defaultDocument enabled="true">
<files>
<add value="index.html" />
</files>
</defaultDocument>
</system.webServer>
</location>
</configuration>
Tomcatサーバーには存在しない http:// localhost/route を要求しているので、404を取得していると思います。 Angular 2はURLの最後にハッシュを使用するのではなく、デフォルトでhtml 5ルーティングを使用するため、ページを更新すると別のリソースを要求するように見えます。
Tomcatで角度ルーティングを使用する場合は、ページを更新しながら、サーバーがアプリ内のすべてのルートをメインのindex.htmlにマッピングするようにする必要があります。この問題を解決するには複数の方法があります。どちらにしてもあなたはそのために行くことができます。
1)展開フォルダのweb.xmlに次のコードを入力します。
<error-page>
<error-code>404</error-code>
<location>/index.html</location>
</error-page>
2)ルートのURLに#を付けてHashLocationStrategyを使用することもできます。
試してみてください。
RouterModule.forRoot(routes、{useHash:true})
の代わりに:
RouterModule.forRoot(ルート)
HashLocationStrategyを使用すると、URLは次のようになります。
3)Tomcat URL Rewrite Valve:リソースが見つからない場合は、サーバーレベルの設定を使用してindex.htmlにリダイレクトするURLを書き換えます。
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]
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エラーを返します。代わりに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": [
"assets",
"favicon.ico",
"Web.config"
],
3)これで、生産用のソリューションを構築できます。
ng build --prod
これはdistフォルダを作成します。 distフォルダ内のファイルはどのモードでもデプロイする準備ができています。
私はそれがどのように機能するのか角度2の種をチェックインしました。
ページがリロードされたときに自動的にリダイレクトするには、 express-history-api-fallback を使用できます。
私はそれがこの問題IMOを解決するための最もエレガントな方法だと思います。
PathLocationStrategyを使いたい場合:
ルートに.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ファイルがメインディレクトリのパスで、プロジェクトのビルドで設定されていることを確認してください。
角度4のApache2でページを更新しながら、ルートに。htaccessを追加するだけで404が解決されました。
<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>
サーバーとして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>
答えはかなり巧妙です。普通のApacheサーバー(またはIIS)を使用している場合、Angularページが実際には存在しないため、問題が発生します。それらはAngularルートから「計算」されます。
この問題を解決するにはいくつかの方法があります。一つはAngularが提供する HashLocationStrategy を使うことです。しかし、URLにシャープなサインが追加されています。これは主にAngular 1との互換性のためです(私は思います)。事実は、シャープ記号の後の部分がURLの一部ではないということです(その後、サーバーは "#"記号の前の部分を解決します)。それは完璧です。
ここで強化された方法(404トリックに基づく)。 Angularアプリケーションの「分散」バージョン(Angular-CLIを使用している場合はng build --prod
)があり、サーバーから直接ページにアクセスし、PHPが有効になっているとします。
Webサイトがページ(Wordpressなど)に基づいていて、Angular専用のフォルダが1つしかない場合(この例では "dist"という名前)、奇妙なことをすることができますが、最後は簡単です。私はあなたがAngularページを "/ dist"に格納していると仮定します(それに応じて<BASE HREF="/dist/">
を付けます)。今度は404リダイレクトとPHPの助けを借りてください。
Apacheの設定(またはAngular Applicationディレクトリの.htaccess
ファイル)に、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
は、角度index.html
のHREFに格納されている値です。
その原理は非常に単純です。Apacheがそのページを見つけられなかった場合、PHPスクリプトに対して404リダイレクトが行われます。ページがAngular Applicationディレクトリ内にあるかどうかを確認します。その場合は、index.htmlを直接(リダイレクトせずに)ロードします。これは、URLを変更しないために必要です。また、HTTPコードを404から200に変更しました(クローラーにはちょうどいいです)。
ページがAngularアプリケーションに存在しない場合はどうなりますか?さて、私たちはアンギュラルーターの "catch all"を使います(Angularルーターのドキュメントを見てください)。
このメソッドは、基本的なWebサイト内に埋め込まれたAngularアプリケーションで機能します(将来的にはそうなると思います)。
ノート:
mod_redirect
(URLを書き換える)で同じことをやろうとすることは全く良い解決策ではありません。なぜならファイル(資産のような)は本当にロードされなければならないからです。ErrorDocument 404 /dist/index.html
を使用してリダイレクトするだけでうまくいきますが、Apacheはまだ404エラーコードで応答しています(これはクローラにとっては悪いことです)。私のAngularルートで定義されているものすべてにマッチし、404ではなくindex.htmlを送り返すハンドラを追加することで(Java/Springバックエンドを使用して)これを修正しました。正しいページをロードします。私はこれで捕まえられないもののために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";
}
}
インポートを追加します。
import { HashLocationStrategy, LocationStrategy } from '@angular/common';
そしてNgModuleプロバイダで、以下を追加してください。
providers: [{provide: LocationStrategy, useClass: HashLocationStrategy}]
アプリのメインのindex.htmlファイルで、ベースhrefを./index.html
から/
に変更します
アプリケーションが任意のサーバーにデプロイされると、任意の外部アプリケーションからアクセスできるページの実際のURLが表示されます。
Angularアプリケーションにnginx Webサーバーを使用している場合は、nginx confファイルのサーバーブロックにtry_files $uri $uri/ /index.html;
を追加するだけです。 ubuntuサーバーの場合、このファイルはdefault.conf
と呼ばれ、/etc/nginx/conf.d
にあります。
/etc/nginx/conf.d # vi default.conf
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log /var/log/nginx/Host.access.log main;
location / {
root /usr/share/nginx/html;
try_files $uri $uri/ /index.html;
index index.html index.htm;
}
}
2017-July-11:これはこの問題を抱えているがElectronでAngular 2を使った質問から リンクされているので 、私はやるよここに私の解決策を追加してください。
私がしなければならなかったのは私のindex.htmlから<base href="./">
を削除することだけでした、そしてElectronはページを再びうまくロードし始めました。
これは恒久的な問題の解決策ではありませんが、回避策やハックのようなものです
私のAngular Appをghページにデプロイするときにも、これと同じ問題がありました。 gh-pagesで自分のページを更新するとき、最初に404メッセージで迎えられました。
それから@gunterが指摘したように私はAngular 2で提供されたHashLocationStrategy
を使い始めました。
しかし、それはそれ自身が問題となっているURLの#
が本当に悪かったため、URLがこのhttps://rahulrsingh09.github.io/AngularConcepts/#/faq
のように見苦しくなっていました。
私はこの問題について調べ始め、ブログに出会いました。私はそれに打撃を与えようとした、そしてそれはうまくいった。
これは私がそのブログで述べたようにしたことです。
あなたのgh-pagesリポジトリに空のHTMLドキュメントを含む404.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組織のサイトを運営している場合は、コンテンツ属性の代替テキストにリポジトリ名を入れないでください。次のようにしてください。content = "0; URL = '/'"
ユーザーが最初にアクセスしたURLを取得して復元するには、他のJavaScriptがページの現在の状態で動作する前に、index.htmlページの先頭に次のscriptタグを追加する必要があります。
<script>
(function(){
var redirect = sessionStorage.redirect;
delete sessionStorage.redirect;
if (redirect && redirect != location.href) {
history.replaceState(null, null, redirect);
}
})();
</script>
このJavaScriptでは、sessionStorageで404.htmlページにキャッシュしたURLを取得し、現在の履歴エントリをそれに置き換えます。
参照 backalleycoder この回避策を提供してくれた@Danielに感謝します。
上記のURLは https://rahulrsingh09.github.io/AngularConcepts/faq に変わります。
「ブラウザのリロードでは動作しない」問題を解決する最善の解決策は、spa-fall backを使用することです。あなたが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" });
});
これは正しい答えではありませんが、リフレッシュ時には404ページを犠牲にすることですべてのデッドコールをHomepageにリダイレクトできます。404.htmlファイルを次のように再生するだけの一時的なハックです。
<!doctype html>
<html>
<head>
<script type="text/javascript">
window.location.href = "http://" + document.location.Host;
</script>
</head>
</html>