Estou usando o React-router e funciona bem enquanto clico nos botões de link, mas quando atualizo minha página da Web, ele não carrega o que quero.
Por exemplo, estou dentro localhost/joblist
e está tudo bem porque cheguei aqui pressionando um link. Mas se eu atualizar a página da Web, recebo:
Cannot GET /joblist
Por padrão, não funcionou assim. Inicialmente, eu tinha o meu URL como localhost/#/
e localhost/#/joblist
e eles funcionou perfeitamente bem. Mas eu não gosto desse tipo de URL, então, tentando apagar isso #
, escrevi:
Router.run(routes, Router.HistoryLocation, function (Handler) {
React.render(<Handler/>, document.body);
});
Este problema não ocorre com localhost/
, este sempre retorna o que eu quero.
EDIT: Este aplicativo é de página única, por /joblist
isso não precisa pedir nada a nenhum servidor.
EDIT2: Meu roteador inteiro.
var routes = (
<Route name="app" path="/" handler={App}>
<Route name="joblist" path="/joblist" handler={JobList}/>
<DefaultRoute handler={Dashboard}/>
<NotFoundRoute handler={NotFound}/>
</Route>
);
Router.run(routes, Router.HistoryLocation, function (Handler) {
React.render(<Handler/>, document.body);
});
javascript
reactjs
url
react-router
DavidDev
fonte
fonte
#
símbolo? Obrigado!index.html
. Isso garantirá queindex.html
seja atingido, não importa o quê.Respostas:
Analisando os comentários sobre a resposta aceita e a natureza genérica dessa pergunta ('não funciona'), achei que esse seria um bom lugar para algumas explicações gerais sobre os problemas envolvidos aqui. Portanto, esta resposta é destinada a informações / elaboração de plano de fundo sobre o caso de uso específico do OP. Por favor, tenha paciência comigo.
Lado do servidor x lado do cliente
A primeira coisa importante a entender sobre isso é que agora existem 2 lugares onde a URL é interpretada, enquanto costumava haver apenas 1 nos 'velhos tempos'. No passado, quando a vida era simples, algum usuário enviava uma solicitação para
http://example.com/about
o servidor, que inspecionava a parte do caminho da URL, determinava que o usuário estava solicitando a página sobre e depois a enviava de volta.Com o roteamento do lado do cliente, que é o que o React-Router fornece, as coisas são menos simples. Inicialmente, o cliente ainda não possui nenhum código JS carregado. Portanto, a primeira solicitação sempre será para o servidor. Isso retornará uma página que contém as tags de script necessárias para carregar o React e o React Router, etc. Somente quando esses scripts foram carregados, a fase 2 é iniciada. Na fase 2, quando o usuário clica no link de navegação "Sobre nós", por exemplo, o URL é alterado localmente apenas para
http://example.com/about
(tornado possível pela API de histórico ), mas nenhuma solicitação ao servidor é feita. Em vez disso, o React Router faz sua parte no lado do cliente, determina qual visualização do React renderizar e a renderiza. Supondo que sua página sobre não precise fazer chamadas REST, isso já foi feito. Você fez a transição da Página inicial para Sobre nós sem que nenhuma solicitação do servidor tenha sido acionada.Então, basicamente, quando você clica em um link, algumas execuções de Javascript que manipulam o URL na barra de endereços, sem causar uma atualização da página , o que faz com que o React Router faça uma transição de página no lado do cliente .
Mas agora considere o que acontece se você copiar e colar o URL na barra de endereços e enviá-lo por e-mail a um amigo. Seu amigo ainda não carregou seu site. Em outras palavras, ela ainda está na fase 1 . O React Router ainda não está em execução em sua máquina. Então, o navegador dela fará uma solicitação ao servidor
http://example.com/about
.E é aí que o seu problema começa. Até agora, você poderia simplesmente colocar um HTML estático na raiz da web do seu servidor. Mas isso daria
404
erros para todos os outros URLs quando solicitados ao servidor . Esses mesmos URLs funcionam bem no lado do cliente , porque o React Router está fazendo o roteamento para você, mas eles falham no lado do servidor, a menos que você faça com que o servidor os entenda.Combinando o roteamento do servidor e do cliente
Se você deseja que o
http://example.com/about
URL funcione no servidor e no cliente, é necessário configurar rotas para ele no servidor e no cliente. Faz sentido certo?E é aí que as suas escolhas começam. As soluções vão desde contornar completamente o problema, por meio de uma rota abrangente que retorna o HTML de inicialização, até a abordagem isomórfica completa, na qual o servidor e o cliente executam o mesmo código JS.
.
Ignorando o problema completamente: Histórico de Hash
Com o Hash History em vez do Browser History , o URL da página about seria parecido com o seguinte:
http://example.com/#/about
A parte após o#
símbolo hash ( ) não é enviada para o servidor. Portanto, o servidor apenas vêhttp://example.com/
e envia a página de índice conforme o esperado. O React-Router pega a#/about
peça e mostra a página correta.Desvantagens :
.
Catch-all
Com essa abordagem, você fazer História Navegador uso, mas apenas configurar um pega-tudo no servidor que envia
/*
paraindex.html
, efetivamente dando-lhe muito a mesma situação que com a História Hash. No entanto, você possui URLs limpos e poderá aprimorar esse esquema posteriormente sem precisar invalidar todos os favoritos do usuário.Desvantagens :
.
Híbrido
Na abordagem híbrida, você expande o cenário abrangente adicionando scripts específicos para rotas específicas. Você pode criar alguns scripts PHP simples para retornar as páginas mais importantes do seu site com o conteúdo incluído, para que o Googlebot possa pelo menos ver o que está na sua página.
Desvantagens :
.
Isomórfico
E se usarmos o Nó JS como nosso servidor para que possamos executar o mesmo código JS nas duas extremidades? Agora, temos todas as nossas rotas definidas em uma única configuração do roteador de reação e não precisamos duplicar nosso código de renderização. Este é 'o Santo Graal', por assim dizer. O servidor envia exatamente a mesma marcação que terminaríamos se a transição da página tivesse acontecido no cliente. Esta solução é ideal em termos de SEO.
Desvantagens :
window
no lado do servidor etc).
Qual devo usar?
Escolha o que você pode se safar. Pessoalmente, acho que o catch-all é simples o suficiente para configurar, então esse seria o meu mínimo. Essa configuração permite que você melhore as coisas ao longo do tempo. Se você já está usando o Node JS como sua plataforma de servidor, eu definitivamente investigaria a execução de um aplicativo isomórfico. Sim, é difícil no começo, mas quando você pega o jeito, na verdade é uma solução muito elegante para o problema.
Então, basicamente, para mim, esse seria o fator decisivo. Se meu servidor for executado no nó JS, eu ficaria isomórfica; caso contrário, eu escolheria a solução Catch-all e a expandiria (solução híbrida) à medida que o tempo avança e os requisitos de SEO exigem.
Se você quiser saber mais sobre a renderização isomórfica (também chamada de 'universal') com o React, existem alguns bons tutoriais sobre o assunto:
Além disso, para você começar, recomendo olhar alguns kits iniciais. Escolha uma que corresponda às suas escolhas para a pilha de tecnologia (lembre-se, React é apenas o V no MVC, você precisa de mais coisas para criar um aplicativo completo). Comece analisando o publicado pelo próprio Facebook:
Ou escolha um dos muitos da comunidade. Existe um site legal agora que tenta indexar todos eles:
Comecei com estes:
Atualmente, estou usando uma versão caseira da renderização universal inspirada nos dois kits iniciais acima, mas eles estão desatualizados agora.
Boa sorte com sua busca!
fonte
/*
e faz com que ela responda com sua página HTML. O mais complicado aqui é garantir que você não intercepte solicitações para os arquivos .js e .css nessa rota.createMemoryHistory is not a function
erro. Importa-se de olhar? stackoverflow.com/questions/45002573/…As respostas aqui são extremamente úteis, o que funcionou para mim foi configurar meu servidor Webpack para esperar as rotas.
O historyApiFallback foi o que corrigiu esse problema para mim. Agora, o roteamento funciona corretamente e eu posso atualizar a página ou digitar o URL diretamente. Não há necessidade de se preocupar com soluções alternativas no servidor do nó. Obviamente, essa resposta só funciona se você estiver usando o webpack.
EDIT: veja minha resposta aqui para uma razão mais detalhada por que isso é necessário: https://stackoverflow.com/a/37622953/5217568
fonte
historyApiFallback
é suficiente. Como para todas as outras opções, também pode ser definido na CLI com o sinalizador--history-api-fallback
.Você pode alterar seu
.htaccess
arquivo e inserir o seguinte:Estou usando
react: "^16.12.0"
ereact-router: "^5.1.2"
Esse método é o Catch-all e provavelmente é a maneira mais fácil de começar.fonte
Para React Router V4 usuários do :
Se você tentar resolver esse problema pela técnica do Hash History mencionada em outras respostas, observe que
não funciona na V4, use
HashRouter
:Referência: HashRouter
fonte
O roteador pode ser chamado de duas maneiras diferentes, dependendo se a navegação ocorre no cliente ou no servidor. Você o configurou para operação no lado do cliente. O parâmetro key é o segundo no método run , a localização.
Quando você usa o componente React Router Link, ele bloqueia a navegação do navegador e chama transição para fazer uma navegação no lado do cliente. Você está usando o HistoryLocation; portanto, ele usa a API de histórico do HTML5 para concluir a ilusão de navegação, simulando o novo URL na barra de endereços. Se você estiver usando navegadores mais antigos, isso não funcionará. Você precisaria usar o componente HashLocation.
Quando você pressiona a atualização, ignora todo o código React e React Router. O servidor recebe a solicitação
/joblist
e deve retornar algo. No servidor, você precisa passar o caminho que foi solicitado aorun
método para que ele renderize a exibição correta. Você pode usar o mesmo mapa de rotas, mas provavelmente precisará de uma chamada diferente paraRouter.run
. Como Charles aponta, você pode usar a reescrita de URL para lidar com isso. Outra opção é usar um servidor node.js. para manipular todas as solicitações e passar o valor do caminho como o argumento de localização.No expresso, por exemplo, pode ser assim:
Observe que o caminho da solicitação está sendo passado para
run
. Para fazer isso, você precisará de um mecanismo de exibição no lado do servidor para o qual possa passar o HTML renderizado. Existem várias outras considerações sobre o usorenderToString
e a execução do React no servidor. Depois que a página é renderizada no servidor, quando o aplicativo é carregado no cliente, ele é renderizado novamente, atualizando o HTML renderizado no servidor, conforme necessário.fonte
No seu index.html
head
, adicione o seguinte:Então, ao executar com o servidor de desenvolvimento webpack, use este comando.
--history-api-fallback
é a parte importantefonte
/
, entãoHashRouter
não vai funcionar (se você estiver usando hash de roteamento)Eu usei o create-react-app para criar um site agora e teve o mesmo problema apresentado aqui. Eu uso
BrowserRouting
doreact-router-dom
pacote. Estou executando em um servidor Nginx e o que o resolveu foi adicionar o seguinte ao/etc/nginx/yourconfig.conf
O que corresponde a adicionar o seguinte ao
.htaccess
caso de você estar executando o AppacheEssa também parece ser a solução sugerida pelo próprio Facebook e pode ser encontrada aqui
fonte
Isso pode resolver seu problema
Também enfrentei o mesmo problema no aplicativo ReactJS no modo de produção. Aqui está a solução 2 para o problema.
1.Altere o histórico de roteamento para "hashHistory" em vez de browserHistory no lugar de
Agora crie o aplicativo usando o comando
Em seguida, coloque a pasta build na sua pasta var / www /. Agora, o aplicativo está funcionando bem com a adição da tag # em cada URL. gostar
localhost / # / home localhost / # / aboutus
Solução 2: sem a tag # usando o browserHistory,
Defina seu history = {browserHistory} em seu roteador, agora construa-o usando sudo npm run build.
Você precisa criar o arquivo "conf" para resolver a página 404 não encontrada, o arquivo conf deve ser assim.
abra o seu terminal digite os comandos abaixo
cd / etc / apache2 / sites-available ls nano sample.conf Adicione o conteúdo abaixo.
Agora você precisa ativar o arquivo sample.conf usando o seguinte comando
então ele solicitará que você recarregue o servidor apache, usando o serviço sudo apache2, recarregue ou reinicie
abra a pasta localhost / build e adicione o arquivo .htaccess com o conteúdo abaixo.
Agora o aplicativo está funcionando normalmente.
Nota: altere 0.0.0.0 ip para o seu endereço IP local.
Se houver alguma dúvida, sinta-se à vontade para comentar.
Espero que seja útil para os outros.
fonte
"react-router-dom": "^5.1.2"
?, Estou usando<BrowserRouter>
Se você estiver hospedando um aplicativo de reação via AWS Static S3 Hosting & CloudFront
Esse problema foi apresentado pelo CloudFront, respondendo com uma mensagem 403 Access Denied, porque esperava que algum / outro / caminho existisse na minha pasta S3, mas esse caminho existe apenas internamente no roteamento do React com o roteador de reação.
A solução foi configurar uma regra de páginas de erro de distribuição. Vá para as configurações do CloudFront e escolha sua distribuição. Em seguida, vá para a guia "Páginas de erro". Clique em "Criar resposta de erro personalizada" e adicione uma entrada para 403, pois esse é o código de status de erro que obtemos. Defina o caminho da página de resposta como /index.html e o código de status como 200. O resultado final me surpreende com sua simplicidade. A página de índice é veiculada, mas o URL é preservado no navegador; portanto, quando o aplicativo de reação é carregado, ele detecta o caminho do URL e navega para a rota desejada.
Regra de páginas 403 de erro
fonte
O Webpack Dev Server tem uma opção para habilitar isso. Abra
package.json
e adicione--history-api-fallback
. Essas soluções funcionaram para mim.Tutorial do react-router
fonte
webpack-dev-server
mas como faço para corrigir isso na construção da produção?Se você estiver hospedando seu aplicativo de reação no IIS, basta adicionar um arquivo web.config contendo:
Isso instruirá o servidor IIS a retornar a página principal ao cliente, em vez do erro 404, sem a necessidade de usar o histórico de hash.
fonte
Adicione isto a
webpack.config.js
:fonte
Pilha de produção: React, React Router v4, BrowswerRouter, Express, Nginx
1) Navegador do usuárioRouter para URLs bonitas
2) Adicione index.html a todas as solicitações desconhecidas usando
/*
3) empacote o webpack com
webpack -p
4) correr
nodemon server.js
ounode server.js
EDIT: você pode deixar o nginx lidar com isso no bloco do servidor e desconsiderar a etapa 2:
fonte
import path from 'path
ouconst path = require('path')
/*
) acabou de salvar meu dia. Obrigado! :)Se você estiver usando o Create React App:
No entanto, há uma grande caminhada sobre esse problema com soluções para muitas das principais plataformas de hospedagem que você pode encontrar AQUI na página Criar aplicativo do React Por exemplo, eu uso o React Router v4 e o Netlify para o meu código de front-end. Bastava adicionar 1 arquivo à minha pasta pública ("_redirects") e uma linha de código nesse arquivo:
Agora, meu site cria corretamente caminhos como mysite.com/pricing quando inserido no navegador ou quando alguém acessa a atualização.
fonte
Tente adicionar o arquivo ".htaccess" dentro da pasta pública com o código abaixo.
fonte
Se você tem um substituto para o seu index.html, verifique se no seu arquivo index.html você tem este:
Isso pode diferir de projeto para projeto.
fonte
head
: <base href = "/">Se você estiver usando o firebase, tudo o que você precisa fazer é garantir que você tenha uma propriedade reescrita no arquivo firebase.json na raiz do seu aplicativo (na seção de hospedagem).
Por exemplo:
Espero que isso poupe a alguém um tesouro de frustração e perda de tempo.
Feliz codificação ...
Leitura adicional sobre o assunto:
https://firebase.google.com/docs/hosting/full-config#rewrites
CLI do Firebase: "Configure como um aplicativo de página única (reescreva todos os URLs em /index.html)"
fonte
Encontrei a solução para o meu SPA com o roteador de reação (Apache). Basta adicionar .htaccess
fonte: https://gist.github.com/alexsasharegan/173878f9d67055bfef63449fa7136042
fonte
Ainda não estou usando a renderização no servidor, mas encontrei o mesmo problema do OP, em que o Link parecia funcionar bem na maioria das vezes, mas falhava quando tinha um parâmetro. Documentarei minha solução aqui para ver se isso ajuda alguém.
Meu jsx principal contém isso:
Isso funciona bem para o primeiro link correspondente, mas quando o: id é alterado
<Link>
expressões aninhadas na página de detalhes desse modelo, o URL é alterado na barra do navegador, mas o conteúdo da página não foi alterado inicialmente para refletir o modelo vinculado.O problema era que eu tinha usado o
props.params.id
para definir o modelocomponentDidMount
. O componente é montado apenas uma vez, o que significa que o primeiro modelo é o que fica na página e os Links subsequentes alteram os acessórios, mas deixam a página inalterada.Definir o modelo no estado do componente em
componentDidMount
e emcomponentWillReceiveProps
(onde é baseado nos próximos objetos) resolve o problema e o conteúdo da página é alterado para refletir o modelo desejado.fonte
props
) isocomponentDidMount
se você quiser tentar a renderização do lado do servidor. PorquecomponentDidMount
é chamado apenas no navegador. Seu objetivo é fazer coisas com o DOM, como anexar ouvintes de eventos abody
etc. que você não pode fazerrender
.Este tópico é um pouco antigo e resolvido, mas eu gostaria de sugerir uma solução simples, clara e melhor. Funciona se você usar um servidor web.
Cada servidor da Web tem a capacidade de redirecionar o usuário para uma página de erro no caso de http 404. Para resolver esse problema, você precisa redirecionar o usuário para a página de índice.
Se você usar o servidor base Java (tomcat ou qualquer servidor de aplicativos java), a solução poderá ser a seguinte:
web.xml:
Exemplo:
É isso, não há mais necessidade mágica :)
fonte
const browserHistory = useRouterHistory(createHistory)({ basename: '/<appname>' });
Se você estiver usando o Express ou alguma outra estrutura no back-end, poderá adicionar a configuração semelhante à abaixo e verificar o caminho público do Webpack na configuração. Ele funcionará bem mesmo ao recarregar se você estiver usando o BrowserRouter
fonte
Corrigindo o erro "não é possível obter / URL" na atualização ou na chamada direta do URL.
Configure o seu webpack.config.js para esperar o link fornecido nas rotas como esta.
fonte
Como estou usando o .Net Core MVC, algo como isto me ajudou:
Basicamente, no lado do MVC, todas as rotas que não corresponderem cairão
Home/Index
conforme especificado emstartup.cs
. No interiorIndex
, é possível obter o URL da solicitação original e passá-lo sempre que necessário.fonte
Se você está hospedando no IIS; Adicionando isso ao meu webconfig resolveu meu problema
Você pode fazer configurações semelhantes para qualquer outro servidor
fonte
Caso alguém esteja aqui procurando uma solução no React JS SPA com o Laravel. A resposta aceita é a melhor explicação de por que esses problemas acontecem. Como já explicado, você deve configurar o lado do cliente e o servidor. No modelo do seu blade, inclua o arquivo compactado js, use-o
URL facade
desta maneiraEm suas rotas, adicione-o ao terminal principal onde está o modelo blade. Por exemplo,
O acima é o ponto final principal do modelo blade. Agora adicione também uma rota opcional,
O problema que acontece é que primeiro o modelo blade é carregado e depois o roteador de reação. Então, quando você está carregando
'/setting-alerts'
, ele carrega o html e os js. Mas quando você carrega'/setting-alerts/about'
, ele primeiro carrega no lado do servidor. Como no lado do servidor, não há nada nesse local, ele retorna não encontrado. Quando você possui esse roteador opcional, ele carrega a mesma página e o roteador de reação também é carregado; o carregador de reatores decide qual componente exibir. Espero que isto ajude.fonte
/user/{userID}
, só preciso retornar uma/user
exibição universal em HTML, trazer o ID e chamá-lo usando AJAX ou axios. É possível fazer isso? eles são amigáveis com SEO?Para aqueles que usam o IIS 10, é isso que você deve fazer para corrigir isso. Certifique-se de estar usando o browserHistory com isso. Quanto à referência, darei o código para o roteamento, mas não é isso que importa, o que importa é o próximo passo após o código do componente abaixo:
Como o problema é que o IIS recebe uma solicitação dos navegadores clientes, ele interpretará a URL como se estivesse solicitando uma página e retornará uma página 404, pois não há uma página disponível. Faça o seguinte:
E agora vai funcionar bem.
Espero que ajude. :-)
fonte
Estou usando o WebPack, tive o mesmo problema Solução => No seu arquivo server.js
Por que meu aplicativo não é renderizado após a atualização?
fonte
Usando
HashRouter
trabalhou para mim com Redux também, basta substituir:para:
fonte
Eu tive esse mesmo problema e essa solução funcionou para nós ..
Fundo:
Estamos hospedando vários aplicativos no mesmo servidor. Quando atualizávamos, o servidor não entendia onde procurar nosso índice na pasta dist para esse aplicativo específico. O link acima o levará ao que funcionou para nós ... Espero que isso ajude, pois passamos muitas horas tentando descobrir uma solução para nossas necessidades.
Nós estamos usando:
meu webpack.config.js
meu index.js
meu app.js
fonte
Eu gosto dessa maneira de lidar com isso. Tente adicionar: yourSPAPageRoute / * no lado do servidor para se livrar desse problema.
Eu segui essa abordagem porque mesmo a API de histórico HTML5 nativa não suporta o redirecionamento correto na atualização da página (tanto quanto eu sei).
Nota: A resposta selecionada já abordou isso, mas estou tentando ser mais específica.
Rota expressa
Testado e só queria compartilhar isso.
Espero que ajude.
fonte