react-router browserHistory 刷新页面 404 问题解决

本文介绍了react-router和browserHistory的原理,对比了browserHistory和hashHistory,阐述了使用browserHistory而非hashHistory的原因,说明了特定作用,给出webpack-dev-server的设置方案,还介绍了browserHistory在服务器端的配置,如BrowserRouter及不同环境下的配置方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

react-router 原理

react-router 是建立在 history 之上的,history 监听浏览器地址栏的变化,解析 URL 然后转换成 location 对象,然后 router 使用它匹配到路由,正确的渲染对应的页面。

browserHistory 原理

browserHistory 使用的是浏览器的 history api,创建一个真实的 URL。

browserHistory 需要进行服务器配置:

使用 browserHistory 需要服务器去配置处理 URL,处理启动最初的 /是没有问题的,但是当路由来回跳转并且在某个路由上进行页面刷新时,服务器接收到来自某个路由的请求,需要处理这个 URL 并且在响应中包含 JavaScript 应用代码。

更多了解:https://react-guide.github.io/react-router-cn/docs/guides/basics/Histories.html

什么是 browserHistory,什么是 hashHistory

history 指的是如何去监听浏览器地址栏的变化

browserHistory 是 HTML5 提供的 History API,使用浏览器提供接口修改历史记录,浏览器上看到的 URL 是这样的:/user/haishanh

hashHistory 是 通过改变地址后面的 hash 来改变浏览器的历史记录,浏览器上看到的 URL 是这样的:/#/user/haishanh?_k=adseis

为什么使用 browserHistory 而不是 hashHistory

  1. 可以使用 pushState() 和 replaceState() 方法来增加或替换历史记录
  2. hash 部分并不会被浏览器发送到服务端,也就是说不管是请求 http://domain.com/index.html#foo 还是 http://domain.com/index.html#bar ,服务只知道请求了 index.html 并不知道 hash 部分的细节
  3. 某些情况会忽略 URL 中的 hash 部分,比如:将 URL 使用微信分享时会丢失 hash 部分

?_k=ckuvup 的作用是什么

当我们使用 window.location.hash = newHash 进行 hash history 跳转时,我们想要全部的 history 都能够使用 location state。

我们就为每一个 location 创建一个唯一的 key,把它们的状态存储在 session storage 中,当访客点击“后退”和“前进”时,我们就会有一个机制去恢复这些 location state。

解决方案:webpack-dev-server 中设置

当使用 HTML5 History API 时,任意的 404 响应都可能需要被替代为 index.html

  • 默认情况下,没有修改 output.publicPath 值

    devServer: {
      historyApiFallback: true;
    }
    
  • 修改了 output.publicPath 值

    // output.publicPath: '/assets/'
    devServer: {
      historyApiFallback: {
        index: "/assets/";
      }
    }
    

官方介绍:https://webpack.docschina.org/configuration/dev-server/#devserver-historyapifallback

browserHistory 的服务器端的配置

BrowserRouter:路由不通过 Hash 完成,显示正常的路径 example.com/some/path,背后调用的是浏览器的 History API。

服务器改造:BrowserRouter 相当于直接向服务器请求某个子路由,会显示网页找不到的 404 错误。使用 webpack-dev-server ,加上 --history-api-fallback 参数

  • webpack 配置
    使用 webpack-dev-server ,启动时加上 --history-api-fallback 参数

或者在 webpack.config.js 文件中:

devServer: {
  historyApiFallback: true;
}
  • express 配置:
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 配置:
server {
...
  location / {
    try_files $uri /index.html
  }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值