关于 Browser 的 History 路由在开发阶段的 404 问题,你有好的解决方法吗?

2019-09-11 10:26:04 +08:00
 shanlan

近期接手了一个 React 项目,这是同事做了七七八八之后交给我的,我也没完整的写过 React 项目。该项目使用了 History 路由,这个路由模式有个缺陷,就是不能直接刷新,否则服务器报错 404,

报错的原因我都知道,但是目前开发的过程很困扰。因为每次修改代码只能回到首页刷新一次,然后再到页面点击需要查看的路径,才能看到修改代码后的效果。

Google 之后基本是推荐更好 Hash 路由,另外由于 WebStorm 的修改代码自动刷新功能,是直接就导致 404 了,难道 History 路由只能强忍着恶心开发吗?

实在是难受!!!

2078 次点击
所在节点    程序员
16 条回复
azh7138m
2019-09-11 10:37:58 +08:00
try file 最后加一个 index.html
一般这样操作
lbw
2019-09-11 11:05:13 +08:00
这就是 history 路由的特性啊,每次路由导航都会真实请求后端页面。本质上 hash 路由是完全由前端主导的路由控制,因为每次 hash 路由导航并不会真实请求 web 服务器,本质上是因为浏览器不会将 hash 路由的锚点请求出去。而 history 路由是真实的路径请求,故每次都会向 web 服务器发送请求,当你 web 服务器没有对应的路由当然就 404 了。

要从本质上解决你的问题简单点的方案就是切 hash 路由,要不你不论是在开发还是生产环境都要配置服务器路由
lbw
2019-09-11 11:22:51 +08:00
@azh7138m 结合楼上的方案,在将所有路由都指向 index.html 后,一些前端路由库,将解析你输入的 url 路径,并进行自动导航,匹配路由组件。
whypool
2019-09-11 11:24:59 +08:00
开发阶段用 hash
learnshare
2019-09-11 11:25:18 +08:00
测试服务器配置有问题吧
Caballarii
2019-09-11 11:29:46 +08:00
开发阶段直接把 browserHistory 改成 hashHistory 好了,打包发布还想用 browserhistory 的话配一下容器转发,非 api 的请求全部重定向到 index.html 就行了
icris
2019-09-11 12:09:35 +08:00
create react app 会创建一个 serviceWorker,给所有请求响应 index.html,可以创建一个然后把 serviceWorker 逻辑复制进项目里
orzorzorzorz
2019-09-11 12:13:50 +08:00
可以试试弄多入口,比如 /test/aaa,那 /test/aaa.html 就是个入口。生产环境改下入口就完了
orzorzorzorz
2019-09-11 12:15:56 +08:00
路由这东西就俩思路,一个是服务端有真东西,一个是客户端造假东西。hash 路由算是异类,不真不假却能用,说实话我觉得挺神奇的,连浏览器都能骗过去
tinytin
2019-09-11 12:18:54 +08:00
用的 webpack dev server 吗,是的话,开启 historyapifallback 就行了
VDimos
2019-09-11 12:26:40 +08:00
盲猜单页面多路由程序,线上环境需要转发到 index.html 下才行,刚踩坑
shanlan
2019-09-11 13:49:46 +08:00
@azh7138m #1 原文:“try file 最后加一个 index.html
一般这样操作”
======
回复:#1

@lbw #3 原文:“@azh7138m 结合楼上的方案,在将所有路由都指向 index.html 后,一些前端路由库,将解析你输入的 url 路径,并进行自动导航,匹配路由组件。”
======
回复:#3 在开发情况下,怎么进行 nginx 重定向?毕竟是热部署,而不是每次修改代码都去 build

@whypool #4 原文:“开发阶段用 hash”
======
回复:#4 后面同事确实是切换到 hash 了


@Caballarii #6 原文:“开发阶段直接把 browserHistory 改成 hashHistory 好了,打包发布还想用 browserhistory 的话配一下容器转发,非 api 的请求全部重定向到 index.html 就行了”
======
回复:#6 目前确实在开发的时候切换到 Hash,我前端白痴,谢谢解答。

@icris #7 原文:“create react app 会创建一个 serviceWorker,给所有请求响应 index.html,可以创建一个然后把 serviceWorker 逻辑复制进项目里”
======
回复:#7 知识盲区,完全听不懂大佬的意思。


@orzorzorzorz #9 原文:“路由这东西就俩思路,一个是服务端有真东西,一个是客户端造假东西。hash 路由算是异类,不真不假却能用,说实话我觉得挺神奇的,连浏览器都能骗过去”
======
回复:#9 浏览器特性吧,路径#后面的浏览器不请求。


@tinytin #10 原文:“用的 webpack dev server 吗,是的话,开启 historyapifallback 就行了”
======
回复:#10 好的,我去了解一下。

@VDimos #11 原文:“盲猜单页面多路由程序,线上环境需要转发到 index.html 下才行,刚踩坑”
======
回复:#11 我自己搭建 nginx 是用转发到 index.html,但是线下开发过程中调试呢?
redbuck
2019-09-11 14:20:29 +08:00
@orzorzorzorz
hash 就是真实的 history.
原本就是用来定位 id 元素的.所以兼容性才好
redbuck
2019-09-11 14:27:27 +08:00
history 路由使用的是 HTML5 新增的 history API,允许你操作浏览器的 history,你可以伪造一个服务器 [没有] 对应响应的访问记录.
所以如果你通过前端路由访问到了某个不存在的路径上,然后刷新页面,这时候访问到后端,请求一个不存在的资源,那自然就 404 了.

所以 history 路由是需要后端配合的.需要使服务器在接到前端路由的 path 时,始终返回那个真实的 html(所谓单页应用,单页就是这个 HTML 了),然后让前端路由介入,解析路径,匹配到对应的前端组件上去.
lbw
2019-09-11 18:29:55 +08:00
@shanlan 是说在开发环境配置 webpack-dev-server 的路由,生产环境下配置 nginx 的路由,开发环境肯定不用每次都 build
shanlan
2019-09-13 16:46:52 +08:00
谢谢各位热情回答,我最后选择在开发过程中使用 HashRoter,其实不麻烦,只需要把 BrowserRoter 改成 HashRoter 即可了。最后构建的时候再换回 Browser,这样就不会有丑陋的#出现在 Url 中,希望我这个方法能解决大家的问题。


@redbuck #13 原文:“@orzorzorzorz
hash 就是真实的 history.
原本就是用来定位 id 元素的.所以兼容性才好”
======
回复:#13

@lbw #15 原文:“@shanlan 是说在开发环境配置 webpack-dev-server 的路由,生产环境下配置 nginx 的路由,开发环境肯定不用每次都 build”
======
回复:#15

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/599908

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX