Heim  >  Artikel  >  Web-Frontend  >  So lösen Sie das Problem mit der React-Router-BrowserHistory-Aktualisierungsseite 404

So lösen Sie das Problem mit der React-Router-BrowserHistory-Aktualisierungsseite 404

小云云
小云云Original
2017-12-29 16:18:343404Durchsuche

Wenn Sie React zum Entwickeln eines neuen Projekts verwenden, die Seite aktualisieren und direkt auf die sekundären oder tertiären Routen zugreifen, schlägt der Zugriff fehl und es tritt eine 404- oder Ressourcenladeausnahme auf. In diesem Artikel wird dieses Problem analysiert und die Lösung zusammengefasst. Dieser Artikel stellt hauptsächlich die Lösung für das 404-Problem der React-Router-History-Aktualisierungsseite vor. Ich hoffe, dass er allen helfen kann.

Hintergrund

Wenn Sie webpack-dev-server als lokalen Entwicklungsserver verwenden, müssen Sie unter normalen Umständen nur einfach den Webpack-dev-Server verwenden. Wenn sich das Projekt jedoch in den folgenden zwei Situationen befindet, sind häufig verschachteltes Routing und asynchrones Laderouting erforderlich:

  1. Wir verwenden eine Routing-Bibliothek wie React-Router um ein Single-Page-Anwendungsrouting zu erstellen;

  2. Verwenden Sie das HTML-Webpack-Plugin, um das 3f1c4e4b6b16bbbd69b2ee476dc4f83a-Tag in das HTML-Dokument einzufügen;

Zu diesem Zeitpunkt besuchen Sie localhost:9090. Seiten, JS und andere Dateien können normal geladen werden, aber wenn wir auf das Routing der zweiten oder sogar dritten Ebene zugreifen oder die Seite aktualisieren müssen, z Als localhost:9090/posts/92 können zwei Situationen auftreten:

  1. Die Seite konnte nicht geladen werden und gab Cannot Get (404) zurück;

  2. Der Dienst hat geantwortet, aber die von der Webpack-Verarbeitung ausgegebene HTML-Datei wurde nicht zurückgegeben, was dazu führte, dass js-Ressourcen nicht geladen werden konnten. Zweitens ist die Situation wie in der Abbildung dargestellt:

Wie gehen wir also damit um, damit wir normal darauf zugreifen und jede Seite weiterleiten können? Der Blogger hat die Quelle ermittelt und das Problem gelöst, nachdem er nach der Dokumentkonfiguration gesucht hatte. Dieser Artikel ist eine Zusammenfassung des gesamten Problemlösungsprozesses.


Analysieren Sie das Problem

Nachdem wir das Problem entdeckt haben, beginnen wir mit der Analyse und Lösung des Problems. Wir gehen davon aus, dass dieses Problem allgemein verursacht wird aus zwei Gründen:

  1. React-Router-Frontend-Konfiguration

  2. Webpack-Dev-Server-Dienstkonfiguration

React-Router

Da das Front-End-Routing Probleme einfacher erkennt, bequemer für die Analyse ist und mit React-Router besser vertraut ist, also zuerst Fragen Sie die React-Router-Routing-Bibliothek ab. Für verwandte Konfigurationsinformationen habe ich festgestellt, dass im Dokument erwähnt wird, dass bei Verwendung von browserHistory eine echte URL erstellt wird und es kein Problem bei der Verarbeitung der ursprünglichen/Anfrage gibt. Wenn Sie die Seite aktualisieren oder direkt auf die URL zugreifen, werden Sie feststellen, dass sie nicht richtig reagiert. Weitere Informationen finden Sie im Referenzdokument. Das Dokument enthält auch mehrere Serverkonfigurationslösungen:


Knoten



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)
wird verwendet Wenn Node als Dienst dient, müssen Sie den Platzhalter * verwenden, um alle Anfragen abzuhören und das Ziel-HTML-Dokument zurückzugeben (HTML, das auf die JS-Ressource verweist). ).


Nginx

Wenn Sie einen Nginx-Server verwenden, müssen Sie nur die try_files-Direktive verwenden:



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

Apache

Wenn Sie den Apache-Server verwenden, müssen Sie eine .htaccess-Datei im Projektstammverzeichnis erstellen Die Datei enthält den folgenden Inhalt:



RewriteBase /
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.html [L]
Die folgenden Konfigurationen für den Server haben wir leider noch nicht eingeführt. Wir verwenden nur den Integrierter Dienst von webpack-dev-server, aber wir haben das Problem gefunden, das heißt, die Routing-Anfrage kann nicht mit dem zurückgegebenen HTML-Dokument übereinstimmen, daher ist es an der Zeit, die Lösung im webpack-dev-server-Dokument zu finden.


webpack-dev-server

Ich muss mich über das offizielle Webpack-dev-server-Dokument hier beschweren. Der Blogger hat es mehrmals gelesen . Ich habe das Problem hier deutlich gesehen:

  1. Der Output.publicPath wird nicht geändert, das heißt, es gibt keinen deklarierten Wert in der Webpack-Konfigurationsdatei die Standardsituation;

  2. Ausgabe.publicPath auf einen benutzerdefinierten Wert setzen

Klicken Sie hier, um das Dokument anzuzeigen


Standardbedingung

Standardmäßig wird der Wert „output.publicPath“ nicht geändert. Sie müssen nur die HistoryApiFallback-Konfiguration von webpack-dev-server festlegen:



devServer: {
 historyApiFallback: true
}
Wenn Sie die HTML5-Verlaufs-API verwenden, müssen Sie wahrscheinlich Ihre index.html anstelle von 404-Antworten bereitstellen, was durch die Einstellung von „historyApiFallback: true“ erreicht werden kann 🎜>


Wenn Ihre App die HTML5-Verlaufs-API verwendet, müssen Sie möglicherweise index.html verwenden, um auf 404- oder Problemanfragen zu reagieren. Legen Sie einfach g HistoryApiFallback: true

Benutzerdefinierter Wert

Wenn Sie jedoch „output.publicPath“ in Ihrer Webpack-Konfiguration geändert haben, müssen Sie die URL angeben, zu der umgeleitet werden soll. Dies erfolgt mit der Option „historyApiFallback.index“

Wenn Sie die Ausgabe in Ihrer Webpack-Konfigurationsdatei geändert haben, müssen Sie die Anforderungsumleitung deklarieren und den Wert „historyApiFallback.index“ konfigurieren.


Proxy
// output.publicPath: '/assets/'
historyApiFallback: {
 index: '/assets/'
}


Ich habe festgestellt, dass die Verwendung der oben genannten Methode mein Problem nicht vollständig lösen wird immer Die Antwort auf die Routing-Anfrage war abnormal, daher suchte der Blogger weiterhin nach einer besseren Lösung:

Klicken Sie hier, um das Dokument anzuzeigen

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: {
 '/': {
  target: 'https://api.example.com',
  secure: false,
  bypass: function(req, res, proxyOptions) {
   if (req.headers.accept.indexOf('html') !== -1) {
    console.log('Skipping proxy for browser request.');
    return '/index.html';
   }
  }
 }
}

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

解决问题

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


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

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

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


historyApiFallback: true

相关推荐:

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

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

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

Das obige ist der detaillierte Inhalt vonSo lösen Sie das Problem mit der React-Router-BrowserHistory-Aktualisierungsseite 404. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn