O roteador Angular 2.0 não está funcionando para recarregar o navegador

189

Estou usando a versão Angular 2.0.0-alpha.30. Quando redirecionar para uma rota diferente, atualize o navegador, mostrando Não é possível obter / rota.

Você pode me ajudar a descobrir por que esse erro aconteceu.

Vinz e Tonz
fonte
1
Eu acho que é stackoverflow.com/questions/16569841
Günter Zöchbauer
Obrigado pela resposta, mas essa é para as versões angulares 1.x. Estou enfrentando o problema no angular 2.0.
Vinz e Tonz 16/07/2015
1
A questão vinculada é um problema geral com o pushState não específico do Angular. Sua pergunta não fornece informações suficientes para saber se está relacionada.
Günter Zöchbauer
5
Angular 2.0 utiliza um novo roteador para que o pós ligada é inútil agora desde o seu velho roteador
Vinz e Tonz
Como eu disse, se for o problema pushState, ele não é específico do Angular e não pode ser corrigido pelo Angular, mas precisa ser corrigido no servidor.
Günter Zöchbauer

Respostas:

141

O erro que você está vendo é porque está solicitando http: // localhost / route que não existe. De acordo com Simon .

Ao usar o roteamento html5, você precisa mapear todas as rotas no seu aplicativo (atualmente 404) para index.html no lado do servidor. Aqui estão algumas opções para você:

  1. usando o servidor ao vivo: https://www.npmjs.com/package/live-server

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

    error_page 404 /index.html
    
  3. Tomcat - configuração do web.xml. Do comentário de Kunin

    <error-page>
          <error-code>404</error-code>
          <location>/index.html</location>
    </error-page>
    
Quy Tang
fonte
1
Como é necessário o suporte do servidor para o roteamento html5, isso funciona perfeitamente bem. Thanx
Prabhat
Posso usar o nginx como proxy pub serve? Dessa forma, eu não preciso pub buildmuito durante o desenvolvimento. Eu tentei, mas proxy_passnão funciona muito bem error_page.
Franklin Yu
@FranklinYu Eu não fiz isso antes. Você resolve isso?
Quy Tang
1
Usando nginx. , error_page 404 /index.html no local do aplicativo funcionou para mim. Obrigado.
Richard K. Campion
2
Tomcat - configuração do web.xml <error-page> <error-code> 404 </error-code> <location> /index.html </location> </error-page>
A Kunin
65

Isenção de responsabilidade: essa correção funciona com Alpha44

Eu tive o mesmo problema e o resolvi implementando o HashLocationStrategy listado na visualização da API do Angular.io.

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

Comece importando as diretivas necessárias

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

E, finalmente, inicialize tudo junto dessa maneira

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

Sua rota aparecerá como http: // localhost / # / route e, quando você atualizar, será recarregada no local apropriado.

Espero que ajude!

SimonHawesome
fonte
1
esse código funcionará bem, mas há algum problema nessa técnica, usando isso #será adicionado automaticamente na URL. existe alguma solução para remover # da URL usando isso?
precisa
Concordo, tentei implementar o "PathLocationStrategy" listado aqui , mas não consegui fazê-lo funcionar. Um URL sem o #seria ideal.
SimonHawesome
Sim, eu também tentei o mesmo com o PathLocationStrategymas isso não está funcionando para mim. ou usei o método errado ou não sei como usar o PathLocationStrategy.
precisa
1
Isso não funciona para mim no RC1. A importação do LocationStrategy, HashLocationStrategy de '@ angular / router' falha.
infojolt
1
Desculpe por voltar a estas perguntas após mais de 1 ano :) Mas o HashLocationStrategy ajuda a permanecer no mesmo caminho do roteador? No meu caso, quando atualizo, leva-me para localhost / # / < rota padrão >, ou seja, a rota padrão para a página inicial. Como vou para a rota atual em que estava originalmente quando 'Atualizei'?
rajugaadu
47

Angular, por padrão, usa o estado push HTML5 ( PathLocationStrategyna gíria Angular).
Você precisa de um servidor que processe todas as solicitações como se estivesse solicitando index.htmlou alterne para HashLocationStrategy(com # no URL para rotas) https://angular.io/docs/ts/latest/api/common/index/HashLocationStrategy-class. html

Consulte também https://ngmilk.rocks/2015/03/09/angularjs-html5-mode-or-pretty-urls-on-apache-using-htaccess/

Para mudar para HashLocationStrategyusar

atualização para> = RC.5 e 2.0.0 final

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

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

ou mais curto com useHash

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

verifique se você tem todas as importações necessárias

Para o novo roteador (RC.3)

<base href="."> 

também pode causar 404.

Em vez disso, requer

<base href="/">

atualização para> = 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';  

atualização para> = beta.16 As importações foram alteradas

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';

Consulte também https://github.com/angular/angular/blob/master/CHANGELOG.md#200-beta16-2016-04-26 breaking-changes

Günter Zöchbauer
fonte
1
Obrigado! fornecer parece ter movido sob / núcleo angular: importação {fornecer} a partir de 'angular2 / núcleo'
StrangeLoop
1
Apenas para observar: update for >= RC.x(RC.2) trabalha com router 3.0.0-alpha.7, mas provideanotou como obsoleto, sem informações sobre qual função o substituiu.
Mrusful
Use{provide: SomeClass, useClass: OtherClass}
Günter Zöchbauer
2
Resposta mais atualizada. Para a versão mais recente do angular 2.4.1, eu tinha <base href = "./">. Alterado para <base href = "/"> resolvido o problema que eu tinha. Pode ser útil para alguém.
Saiyaff Farouk
28

Eu acho que o erro que você está vendo é porque você está solicitando http: // localhost / route que não existe. Você precisa garantir que seu servidor mapeie todas as solicitações para sua página principal index.html.

Como o Angular 2 usa o roteamento html5 por padrão, em vez de usar hashes no final do URL, a atualização da página parece uma solicitação de um recurso diferente.

Simon
fonte
7
então, como consertamos isso? como mapeamos todos os pedidos para o índice principal por padrão? é dependente do servidor?
21416 Ayyash
1
Sim, você faria isso no servidor com qualquer estrutura da web que estiver usando. A alternativa é usar o HashLocationStrategy conforme descrito abaixo.
18716 Simon
Você recarregará o SPA angular em todas as rotas ausentes. É assim que deve ser tratado?
Gary
Ele é recarregado apenas se o usuário clicar em atualizar no navegador, não quando o usuário alterar as rotas pela interface do usuário. Realmente não há uma maneira de contornar uma recarga quando o usuário atualiza.
Wallace Howery
19

Essa é uma situação comum em todas as versões do roteador se você estiver usando a estratégia de localização HTML padrão.

O que acontece é que o URL na barra do navegador é um URL HTML completo normal, como por exemplo: http://localhost/route .

Portanto, quando pressionamos Enter na barra do navegador, há uma solicitação HTTP real enviada ao servidor para obter um arquivo chamado route.

O servidor não possui esse arquivo e nem algo como express está configurado no servidor para manipular a solicitação e fornecer uma resposta; portanto, o servidor retorna 404 Não encontrado, porque não foi possível encontrar o routearquivo.

O que queremos é que o servidor retorne o index.htmlarquivo que contém o aplicativo de página única. Em seguida, o roteador deve iniciar e processar o /routeURL e exibir o componente mapeado para ele.

Portanto, para corrigir o problema, precisamos configurar o servidor para retornar index.html (supondo que esse seja o nome do seu arquivo de aplicativo de página única) caso a solicitação não possa ser tratada, em vez de 404 não encontrado.

A maneira de fazer isso dependerá da tecnologia do servidor que está sendo usada. Se for Java, por exemplo, você pode precisar escrever um servlet, no Rails será diferente etc.

Para dar um exemplo concreto, se, por exemplo, você estiver usando NodeJs, seria necessário escrever um middleware como este:

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

E, em seguida, registre-o no final da cadeia de middleware:

app.use(sendSpaFileIfUnmatched);

Isso servirá em index.htmlvez de retornar um 404, o roteador entrará em ação e tudo funcionará conforme o esperado.

Universidade Angular
fonte
Esse foi exatamente o meu problema. Se você usa o NGINX, esta resposta ajuda a resolvê-lo: stackoverflow.com/questions/7027636/…
Nathan
Existe um tutorial sobre como fazer isso para java? Obrigado.
000000000000000000000
13

Verifique se isso foi colocado no elemento principal do seu index.html:

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

O Exemplo na documentação de Roteamento e Navegação Angular2 usa o seguinte código no cabeçalho (eles explicam o motivo na nota de exemplo ao vivo da documentação):

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

Quando você atualiza uma página, isso define dinamicamente o href base para o seu document.location atual. Eu pude ver isso causando alguma confusão para as pessoas que vasculharam a documentação e tentaram replicar o plunker.

user2263572
fonte
Obrigado por compartilhar isso. Vamos deixar claro: ele só funcionou para mim quando eu coloquei <base href = "/"> diretamente após carregar todos os css no <head> e antes de carregar QUALQUER arquivo Js. Espero que ajude alguém
wmehanna
Eu tenho <base href = "./"> em index.html e removi '.' do href e funcionou ..
Saurabh Solanki
10

Se você deseja inserir URLs no navegador sem configurar o AppServer para lidar com todas as solicitações de index.html, use o HashLocationStrategy .

A maneira mais fácil de configurar é usando:

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

Ao invés de:

RouterModule.forRoot(routes)

Com o HashLocationStrategy, seus URLs serão como:

http://server:port/#/path
felipecrp
fonte
Obrigado! isso ajuda, mas eu não quero #do url, podemos remover isso?
Hidayt Rahman 12/04/19
7

Eu tive o mesmo problema ao usar o webpack-dev-server. Eu tive que adicionar a opção devServer ao meu webpack.

Solução:

// in webpack
devServer: {
    historyApiFallback: true,
    stats: 'minimal'
}
angmerica
fonte
Tipo de magia vodu: p Para mais informações, consulte: webpack.github.io/docs/...
Jissay
7

Se você estiver usando o Apache ou o Nginx como servidor, precisará criar um .htaccess(se não criado antes) e RewriteEngine "On"

RewriteEngine On  
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteRule ^ - [L]
RewriteRule ^ /index.html
Rakesh Roy
fonte
Não obter a sua pergunta, este método testado em Apache e Nginx ( nginx.com servidor)
Rakesh Roy
1
Isso é apenas para Apache; O formato de configuração do Nginx é totalmente diferente.
Franklin Yu
5

Meu servidor é o Apache, o que fiz para corrigir o 404 ao atualizar ou criar links diretos é muito simples. Basta adicionar uma linha na configuração do apache vhost:

ErrorDocument 404 /index.html

Para que qualquer erro 404 seja redirecionado para index.html, que é o que o roteamento angular2 deseja.

O exemplo completo do arquivo vhost:

<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>

Não importa qual servidor você esteja usando, acho que o ponto principal é descobrir as maneiras de configurar o servidor para redirecionar 404 para o seu index.html.

Willie Z
fonte
4

A configuração do servidor não é uma solução para um SPA, é o que eu acho. Você não deseja recarregar um SPA angular novamente se uma rota errada aparecer, não é? Portanto, não vou depender de uma rota do servidor e redirecionar para outra rota, mas sim, deixarei o index.html manipular todos os pedidos de rotas angulares do caminho angular do aplicativo.

Tente isso em vez de rotas diferentes ou incorretas. Funciona para mim, não tenho certeza, mas parece um trabalho em andamento. Eu me deparei com isso quando enfrentava um problema.

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

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

No entanto, lembre-se de configurar as pastas do servidor e acessar corretamente, caso você tenha scripts HTML ou da web que não são SPA. Caso contrário, você enfrentará problemas. Para mim, quando enfrentava um problema como você, era uma mistura de configurações do servidor e acima.

Gary
fonte
4

para a correção rápida angular 5, edite app.module.ts e adicione {useHash:true}após os appRoutes.

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

Aplicativos angulares são candidatos perfeitos para servir com um servidor HTML estático simples. Você não precisa de um mecanismo do lado do servidor para compor dinamicamente as páginas do aplicativo, porque o Angular faz isso no lado do cliente.

Se o aplicativo usar o roteador Angular, você deverá configurar o servidor para retornar a página host do aplicativo (index.html) quando for solicitado um arquivo que ele não possui.

Um aplicativo roteado deve suportar "links diretos". Um link direto é um URL que especifica o caminho para um componente dentro do aplicativo. Por exemplo, http://www.example.com/heroes/42 é um link direto para a página de detalhes do herói que exibe o herói com o ID: 42.

Não há problema quando o usuário navega para esse URL de dentro de um cliente em execução. O roteador Angular interpreta o URL e as rotas para essa página e herói.

Mas clicar em um link em um email, inseri-lo na barra de endereços do navegador ou simplesmente atualizar o navegador na página de detalhes do herói - todas essas ações são tratadas pelo próprio navegador, fora do aplicativo em execução. O navegador faz uma solicitação direta ao servidor para esse URL, ignorando o roteador.

Um servidor estático retorna rotineiramente index.html quando recebe uma solicitação para http://www.example.com/ . Mas ele rejeita http://www.example.com/heroes/42 e retorna um erro 404 - Não encontrado, a menos que esteja configurado para retornar index.html

Se esse problema ocorreu na produção, siga as etapas abaixo

1) Adicione um arquivo Web.Config na pasta src do seu aplicativo angular. Coloque o código abaixo nele.

<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) Adicione uma referência a ele em angular-cli.json. Em angular-cli.json, coloque Web.config no bloco de ativos, como mostrado abaixo.

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

3) Agora você pode criar a solução para produção usando

ng build --prod

Isso criará uma pasta dist. Os arquivos dentro da pasta dist estão prontos para implantação em qualquer modo.

Malatesh Patil
fonte
A melhor solução é encontrar os detalhes em angular: angular.io/guide/deployment#fallback Ao criar o arquivo web.config, não se esqueça de adicionar a tag <configuration> </configuration>. Obrigado pela resposta Malatesh.
Palash Roy
3

Você pode usar esta solução para aplicação média, usei o ejs como mecanismo de exibição:

// 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');
});

e também definido em angular-cli.json

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

funcionará bem em vez de

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

está criando um problema com as chamadas get db e retornando index.html

Shoaib Qureshi
fonte
1
Isso funcionou perfeitamente em outubro de 2017 para o aplicativo de pilha MEAN.
Mindsect Team
2

Para aqueles de nós que lutamos pela vida no IIS: use o seguinte código do PowerShell para corrigir esse problema com base nos documentos oficiais do Angular 2 (que alguém postou neste tópico? 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

Isso redireciona o 404 para o arquivo /index.html conforme a sugestão dos documentos do Angular 2 (link acima).

Jim Hume
fonte
2

Você pode experimentar abaixo. Funciona para mim!

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() { }
}

Você pode aprimorar ainda mais o path.substr (2) para dividir em parâmetros do roteador. Estou usando o angular 2.4.9

Kaifeong
fonte
Isso foi realmente útil para lidar com as atualizações do navegador! Para o angular 5, tive que modificá-lo um pouco para usar window.location.pathname e comparar esse valor aos caminhos esperados.
Wallace Howery
2

i Apenas adicionando .htaccess na raiz.

<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>

aqui, basta adicionar o ponto '.' (diretório pai) em /index.html para ./index.html.
Verifique se o arquivo index.html no caminho base é o caminho do diretório principal e definido na construção do projeto.

hadiya vipul
fonte
1

Eu queria preservar o caminho da URL das subpáginas no modo HTML5 sem redirecionar de volta para o índice e nenhuma das soluções disponíveis me disse como fazer isso, então foi assim que eu consegui:

Crie diretórios virtuais simples no IIS para todas as suas rotas e aponte-os para a raiz do aplicativo.

Envolva seu system.webServer no seu Web.config.xml com essa tag de localização, caso contrário você receberá erros duplicados ao carregar o Web.config uma segunda vez com o diretório virtual:

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

Eu verifiquei no angular 2 sementes como ele funciona.

Você pode usar express-history-api-fallback para redirecionar automaticamente quando uma página é recarregada.

Eu acho que é a maneira mais elegante de resolver esse problema IMO.

Lievno
fonte
1

Se você deseja usar PathLocationStrategy:

  • Configuração do Wildfly:
    • Crie o arquivo undertow-handlers.conf para ser colocado no WEB-INF
    • Conteúdo: (exclua os pontos de extremidade restantes!)
      • regex ['(. / overview / ? . ? $)'] e não regex ['(. / endpoints. )'] -> reescrever ['/ index.html']
      • regex ['(. / deployments / ? . ? $)'] e não regex ['(. / endpoints. )'] -> reescrever ['/ index.html']

Aplicativo de página única com Java EE / Wildfly: configuração do lado do servidor

nkeymeulen
fonte
1

2017-July-11: Como isso está vinculado a uma pergunta com esse problema, mas usando Angular 2 com Electron, adicionarei minha solução aqui.

Tudo o que eu precisava fazer era remover <base href="./">do meu index.html e o Electron começou a recarregar a página novamente com sucesso.

TimTheEnchanter
fonte
1

Adicionar importações:

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

E no provedor NgModule, adicione:

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

No arquivo principal index.html do aplicativo, altere o href base para ./index.htmlde/

O aplicativo, quando implantado em qualquer servidor, fornecerá um URL real para a página que pode ser acessada a partir de qualquer aplicativo externo.

Debargho24
fonte
1

Apenas adicionar .htaccess na raiz resolveu 404 enquanto atualizava a página no angular 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>
a_k_v
fonte
1

Eu acho que você está recebendo 404 porque está solicitando http: // localhost / route que não existe no servidor tomcat. Como o Angular 2 usa o roteamento html 5 por padrão, em vez de usar hashes no final da URL, a atualização da página parece uma solicitação de um recurso diferente.

Ao usar o roteamento angular no tomcat, você precisa garantir que o servidor mapeie todas as rotas no seu aplicativo para o seu principal index.html enquanto atualiza a página. Existem várias maneiras de resolver esse problema. Qualquer que seja o seu gosto, você pode fazer isso.

1) Coloque o código abaixo em web.xml da sua pasta de implantação:

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

2) Você também pode tentar usar o HashLocationStrategy com # no URL para rotas:

Tente usar:

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

Ao invés de:

RouterModule.forRoot (rotas)

Com o HashLocationStrategy, seus URLs serão como:

http: // localhost / # / route

3) Válvula de reescrita de URL do Tomcat: reescreva os URLs usando uma configuração no nível do servidor para redirecionar para index.html se o recurso não for encontrado.

3.1) Dentro da pasta META-INF, crie um arquivo context.xml e copie o contexto abaixo dentro dele.

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

3.2) Dentro de WEB-INF, crie o arquivo rewrite.config (este arquivo contém a regra para regravação de URL e usada pelo tomcat para regravação de URL). Dentro de rewrite.config, copie o conteúdo abaixo:

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

Esta não é a resposta certa, mas na atualização, você pode redirecionar todas as chamadas mortas para a Página inicial, sacrificando a página 404.

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

A melhor solução para resolver o "roteador que não funciona ao recarregar o navegador" é que devemos usar o spa-fall back. Se você estiver usando o aplicativo angular2 com o núcleo do asp.net, precisamos defini-lo na página "StartUp.cs". sob roteadores MVC. Estou anexando o código.

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

A resposta é bastante complicada. Se você usar um servidor Apache antigo (ou IIS) simples, obterá o problema porque as páginas angulares não existem de verdade. Eles são "computados" a partir da rota angular.

Existem várias maneiras de corrigir o problema. Uma é usar o HashLocationStrategy oferecido pela Angular. Mas um sinal nítido é adicionado ao URL. Isto é principalmente para compatibilidade com o Angular 1 (presumo). O fato é que a parte depois que o sharp não faz parte da URL (o servidor resolve a parte antes do sinal "#"). Isso pode ser perfeito.

Aqui está um método aprimorado (baseado no truque 404). Suponho que você tenha uma versão "distribuída" do seu aplicativo angular ( ng build --prodse você usa o Angular-CLI) e acessa as páginas diretamente com o servidor e o PHP está ativado.

Se o seu site é baseado em páginas (Wordpress, por exemplo) e você tem apenas uma pasta dedicada ao Angular (chamada "dist" no meu exemplo), você pode fazer algo estranho, mas, no final, simples. Suponho que você tenha armazenado suas páginas angulares em "/ dist" (de acordo <BASE HREF="/dist/">). Agora use um redirecionamento 404 e a ajuda do PHP.

Na configuração do Apache (ou no .htaccessarquivo do diretório angular do aplicativo), você deve adicionarErrorDocument 404 /404.php

O 404.php começará com o seguinte código:

<?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>"

Onde $angularé o valor armazenado no HREF do seu angular index.html.

O princípio é bastante simples: se o Apache não encontrar a página, será feito um redirecionamento 404 para o script PHP. Apenas verificamos se a página está dentro do diretório angular do aplicativo. Se for o caso, basta carregar o index.html diretamente (sem redirecionar): isso é necessário para manter o URL inalterado. Também alteramos o código HTTP de 404 para 200 (melhor para rastreadores).

E se a página não existir no aplicativo angular? Bem, usamos o "catch all" do roteador angular (consulte a documentação do roteador angular).

Esse método funciona com um aplicativo Angular incorporado em um site básico (acho que será o caso no futuro).

NOTAS:

  • Tentar fazer o mesmo com a mod_redirect(reescrevendo os URLs) não é de todo uma boa solução, porque os arquivos (como ativos) precisam ser realmente carregados; portanto, é muito mais arriscado do que usar a solução "não encontrada".
  • Apenas redirecionando usando o ErrorDocument 404 /dist/index.htmlWorks, mas o Apache ainda está respondendo com um código de erro 404 (o que é ruim para os rastreadores).
William R
fonte
0

Esta não é uma correção permanente para o problema, mas mais como uma solução alternativa ou invasão

Eu tive esse mesmo problema ao implantar meu aplicativo Angular em páginas gh. Primeiro, fui recebido com 404 mensagens ao atualizar minhas páginas nas páginas gh.

Então, como o @gunter apontou, comecei a usar HashLocationStrategy que era fornecido com o Angular 2.

Mas isso veio com o seu próprio conjunto de problemas, #pois o URL era muito ruim e fazia com que o URL parecesse estranhohttps://rahulrsingh09.github.io/AngularConcepts/#/faq .

Comecei a pesquisar sobre esse problema e me deparei com um blog. Eu tentei tentar e funcionou.

Aqui está o que eu fiz como mencionado nesse blog.

Você precisará começar adicionando um arquivo 404.html ao seu repositório gh-pages que contenha um documento HTML vazio dentro dele - mas seu documento deve totalizar mais de 512 bytes (explicado abaixo). Em seguida, coloque a seguinte marcação no elemento principal da sua página 404.html:

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

Esse código define o URL de entrada tentado como uma variável no objeto sessionStorage padrão e redireciona imediatamente para a página index.html do seu projeto usando uma tag de atualização meta. Se você estiver criando um site da Organização Github, não coloque um nome de repo no texto substituto do atributo content, faça o seguinte: content = "0; URL = '/'"

Para capturar e restaurar o URL para o qual o usuário navegou inicialmente, você precisará adicionar a seguinte tag de script no cabeçalho da página index.html antes que qualquer outro JavaScript atue no estado atual da página:

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

Esse bit de JavaScript recupera o URL que armazenamos em cache em sessionStorage na página 404.html e substitui a entrada do histórico atual por ela.

Referência backalleycoder Graças a @ Daniel para esta solução alternativa.

Agora, o URL acima muda para https://rahulrsingh09.github.io/AngularConcepts/faq

Rahul Singh
fonte
0

Corrigi isso (usando Java / Spring back-end) adicionando um manipulador que corresponde a tudo definido em minhas rotas Angular, que envia index.html em vez de 404. Isso então efetivamente (re) inicializa o aplicativo e carrega a página correta. Eu também tenho um manipulador 404 para qualquer coisa que não seja capturada por isso.

@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";
    }
}
Lee Willis
fonte
0

Se você estiver usando Apache ou Nginx como servidor, precisará criar um arquivo .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>
Mukesh Kumar Bijarniya
fonte