V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
shanlan
V2EX  ›  程序员

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

  •  
  •   shanlan · 2019-09-11 10:26:04 +08:00 · 2235 次点击
    这是一个创建于 1900 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

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

    实在是难受!!!

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

    要从本质上解决你的问题简单点的方案就是切 hash 路由,要不你不论是在开发还是生产环境都要配置服务器路由
    lbw
        3
    lbw  
       2019-09-11 11:22:51 +08:00
    @azh7138m 结合楼上的方案,在将所有路由都指向 index.html 后,一些前端路由库,将解析你输入的 url 路径,并进行自动导航,匹配路由组件。
    whypool
        4
    whypool  
       2019-09-11 11:24:59 +08:00   ❤️ 1
    开发阶段用 hash
    learnshare
        5
    learnshare  
       2019-09-11 11:25:18 +08:00
    测试服务器配置有问题吧
    Caballarii
        6
    Caballarii  
       2019-09-11 11:29:46 +08:00   ❤️ 1
    开发阶段直接把 browserHistory 改成 hashHistory 好了,打包发布还想用 browserhistory 的话配一下容器转发,非 api 的请求全部重定向到 index.html 就行了
    icris
        7
    icris  
       2019-09-11 12:09:35 +08:00   ❤️ 1
    create react app 会创建一个 serviceWorker,给所有请求响应 index.html,可以创建一个然后把 serviceWorker 逻辑复制进项目里
    orzorzorzorz
        8
    orzorzorzorz  
       2019-09-11 12:13:50 +08:00
    可以试试弄多入口,比如 /test/aaa,那 /test/aaa.html 就是个入口。生产环境改下入口就完了
    orzorzorzorz
        9
    orzorzorzorz  
       2019-09-11 12:15:56 +08:00
    路由这东西就俩思路,一个是服务端有真东西,一个是客户端造假东西。hash 路由算是异类,不真不假却能用,说实话我觉得挺神奇的,连浏览器都能骗过去
    tinytin
        10
    tinytin  
       2019-09-11 12:18:54 +08:00 via iPhone
    用的 webpack dev server 吗,是的话,开启 historyapifallback 就行了
    VDimos
        11
    VDimos  
       2019-09-11 12:26:40 +08:00 via Android
    盲猜单页面多路由程序,线上环境需要转发到 index.html 下才行,刚踩坑
    shanlan
        12
    shanlan  
    OP
       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
        13
    redbuck  
       2019-09-11 14:20:29 +08:00
    @orzorzorzorz
    hash 就是真实的 history.
    原本就是用来定位 id 元素的.所以兼容性才好
    redbuck
        14
    redbuck  
       2019-09-11 14:27:27 +08:00
    history 路由使用的是 HTML5 新增的 history API,允许你操作浏览器的 history,你可以伪造一个服务器 [没有] 对应响应的访问记录.
    所以如果你通过前端路由访问到了某个不存在的路径上,然后刷新页面,这时候访问到后端,请求一个不存在的资源,那自然就 404 了.

    所以 history 路由是需要后端配合的.需要使服务器在接到前端路由的 path 时,始终返回那个真实的 html(所谓单页应用,单页就是这个 HTML 了),然后让前端路由介入,解析路径,匹配到对应的前端组件上去.
    lbw
        15
    lbw  
       2019-09-11 18:29:55 +08:00
    @shanlan 是说在开发环境配置 webpack-dev-server 的路由,生产环境下配置 nginx 的路由,开发环境肯定不用每次都 build
    shanlan
        16
    shanlan  
    OP
       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
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2197 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 01:30 · PVG 09:30 · LAX 17:30 · JFK 20:30
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.