Maison  >  Article  >  interface Web  >  Comment résoudre le problème de la page 404 d'actualisation de l'historique du navigateur React-Router

Comment résoudre le problème de la page 404 d'actualisation de l'historique du navigateur React-Router

小云云
小云云original
2017-12-29 16:18:343403parcourir

Lors de l'utilisation de React pour développer un nouveau projet, lors de l'actualisation de la page et de l'accès direct aux routes secondaires ou tertiaires, l'accès échoue et une exception 404 ou de chargement de ressources se produit. Cet article analyse ce problème et résume la solution. Cet article présente principalement la solution au problème 404 de la page d'actualisation de l'historique du navigateur React-Router. Il est d'une grande valeur pratique. Les amis dans le besoin peuvent s'y référer. J'espère que cela pourra aider tout le monde.

Contexte

Lorsque vous utilisez webpack-dev-server comme serveur de développement local, dans des circonstances normales, il vous suffit d'utiliser simplement le webpack-dev- commande du serveur pour le démarrer. Cependant, lorsque le projet se trouve dans les deux situations suivantes, un routage imbriqué et un routage à chargement asynchrone sont souvent nécessaires :

  1. Nous utilisons une bibliothèque de routage telle que React-Router. pour créer un routage d'application sur une seule page ;

  2. Utilisez le plug-in html-webpack-plugin pour injecter dynamiquement la balise 3f1c4e4b6b16bbbd69b2ee476dc4f83a

À ce moment, visitez localhost:9090 Les pages et js et autres fichiers peuvent être chargés normalement, mais lorsque nous devons accéder au routage secondaire ou même tertiaire ou actualiser la page, comme localhost:9090/ posts/92, ​​​​deux situations peuvent se produire :

  1. La page n'a pas pu se charger et a renvoyé Cannot Get (404)

  2. Le service ; a répondu, mais le fichier html généré par le traitement webpack n'a pas été renvoyé, ce qui a entraîné l'échec du chargement des ressources js. Deuxièmement, la situation est celle illustrée dans la figure :

Alors, comment pouvons-nous le gérer pour pouvoir y accéder normalement et acheminer chaque page ? Le blogueur a retracé la source et résolu le problème après avoir recherché la configuration du document. Cet article est un résumé de l'ensemble du processus de résolution du problème.


Analyser le problème


Après avoir découvert le problème, nous commencerons à analyser et à résoudre le problème. Nous jugeons que ce problème est généralement causé. pour deux raisons :

    configuration frontale du routeur React ;
  1. configuration du service webpack-dev-server
react-router


Parce que le routage frontal est plus facile à identifier les problèmes, plus pratique pour l'analyse et plus familier avec React-Router, alors d'abord interrogez la bibliothèque de routage React-Router Pour les informations de configuration associées, j'ai trouvé que le document mentionnait que lors de l'utilisation de BrowserHistory, une véritable URL serait créée et qu'il n'y aurait aucun problème dans le traitement de la demande initiale. Cependant, après avoir accédé à l'itinéraire, En actualisant la page ou en accédant directement à l'URL, vous constaterez qu'elle ne peut pas répondre correctement. Plus Consultez le document de référence pour plus d'informations. Le document fournit également plusieurs solutions de configuration du serveur :


Node



est en cours d'utilisation Lorsque Node sert de service, il doit utiliser le caractère générique * pour écouter toutes les requêtes et renvoyer le document html cible (html faisant référence à la ressource js ).

const express = require('express')
const path = require('path')
const port = process.env.PORT || 8080
const app = express()

// 通常用于加载静态资源
app.use(express.static(__dirname + '/public'))

// 在你应用 JavaScript 文件中包含了一个 script 标签
// 的 index.html 中处理任何一个 route
app.get('*', function (request, response){
 response.sendFile(path.resolve(__dirname, 'public', 'index.html'))
})

app.listen(port)
console.log("server started on port " + port)


Nginx

Si vous utilisez le serveur nginx, il vous suffit d'utiliser la directive try_files :



Apache
server {
 ...
 location / {
  try_files $uri /index.html
 }
}

Si vous utilisez le serveur Apache, vous devez créer un fichier .htaccess dans le répertoire racine du projet. Le fichier contient le contenu suivant :



Voici les configurations du serveur. Malheureusement, nous n'avons pas encore introduit le serveur concerné. Nous utilisons simplement le. service intégré de webpack-dev-server, mais nous avons trouvé le problème, c'est-à-dire que la demande de routage ne peut pas correspondre au document HTML renvoyé, il est donc temps de trouver la solution dans le document webpack-dev-server.

RewriteBase /
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.html [L]


webpack-dev-server

Je dois me plaindre du document officiel webpack-dev-server ici Le blogueur l'a lu plusieurs fois. . , j'ai clairement vu le problème. Il y a deux situations ici :

Le output.publicPath n'est pas modifié, c'est-à-dire qu'il n'y a pas de valeur déclarée dans le fichier de configuration du webpack, ce qui est le cas. la situation par défaut ;
  1. Définissez output.publicPath sur une valeur personnalisée
  2. Cliquez ici pour afficher le document


Condition par défaut

Par défaut, la valeur output.publicPath n'est pas modifiée. Il vous suffit de définir la configuration historyApiFallback de webpack-dev-server :
<.>


Si vous utilisez l'API d'historique HTML5, vous devrez probablement servir votre index.html à la place des réponses 404, ce qui peut être fait en définissant historyApiFallback : true

devServer: {
 historyApiFallback: true
}
Si votre application utilise l'API d'historique HTML5, vous devrez peut-être utiliser index.html pour répondre aux demandes 404 ou aux problèmes, définissez simplement g historyApiFallback : true


Valeur personnalisée

Cependant, si vous avez modifié output.publicPath dans la configuration de votre Webpack, vous devez spécifier l'URL vers laquelle rediriger. Cela se fait à l'aide de l'option historyApiFallback.index

. Si vous avez modifié la sortie dans la valeur publicPath de votre fichier de configuration Webpack, vous devez alors déclarer la redirection de la demande et configurer la valeur historyApiFallback.index.



Procuration

// output.publicPath: &#39;/assets/&#39;
historyApiFallback: {
 index: &#39;/assets/&#39;
}

J'ai trouvé que l'utilisation de la méthode ci-dessus ne résout pas complètement mon problème. toujours être La réponse à la demande de routage était anormale, le blogueur a donc continué à chercher une meilleure solution :

Cliquez ici pour voir le document

The proxy can be optionally bypassed based on the return from a function. The function can inspect the HTTP request, response, and any given proxy options. It must return either false or a URL path that will be served instead of continuing to proxy the request.

代理提供通过函数返回值响应请求方式,针对不同请求进行不同处理,函数参数接收HTTP请求和响应体,以及代理配置对象,这个函数必须返回false或URL路径,以表明如何继续处理请求,返回URL时,源请求将被代理到该URL路径请求。


proxy: {
 &#39;/&#39;: {
  target: &#39;https://api.example.com&#39;,
  secure: false,
  bypass: function(req, res, proxyOptions) {
   if (req.headers.accept.indexOf(&#39;html&#39;) !== -1) {
    console.log(&#39;Skipping proxy for browser request.&#39;);
    return &#39;/index.html&#39;;
   }
  }
 }
}

如上配置,可以监听https://api.example.com域下的/开头的请求(等效于所有请求),然后判断请求头中accept字段是否包含html,若包含,则代理请求至/index.html,随后将返回index.html文档至浏览器。

解决问题

综合以上方案,因为在webpack配置中修改了output.publicPath为/assets/,所以博主采用webpack-dev-server Proxy代理方式解决了问题:


const PUBLICPATH = &#39;/assets/&#39;
...
proxy: {
 &#39;/&#39;: {
  bypass: function (req, res, proxyOptions) {
   console.log(&#39;Skipping proxy for browser request.&#39;)
   return `${PUBLICPATH}/index.html`
  }
 }
}

监听所有前端路由,然后直接返回${PUBLICPATH}/index.html,PUBLICPATH就是设置的output.publicPath值。

另外,博主总是习惯性的声明,虽然不设置该属性也能满足预期访问效果:


historyApiFallback: true

相关推荐:

使用Django实现自定义404,500页面的方法

IDEA导入web项目详解(解决访问的404)

thinkphp制作404跳转页的简单实现方法

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn