再在App.vue页面js代码里引入provide方法并在data中声明变量isRouterAlive以及在method中添加reload方法export default { name: 'app', provide() { return { _springboot vue 404">
当前位置:   article > 正文

Vue + SpringBoot项目服务器部署后浏览器刷新页面404错误分析和解决方案_springboot vue 404

springboot vue 404

先贴解决方案代码,再分析原因

VUE前端代码

在App.vue页面的routet-view中加入v-if代码

<router-view v-if="isRouterAlive"></router-view>
  • 1

再在App.vue页面js代码里引入provide方法并在data中声明变量isRouterAlive以及在method中添加reload方法

export default {
  name: 'app',
    provide() {
        return {
            reload: this.reload
        }
    },
     data() {
    	return {
	      isRouterAlive: true
    	};
  	},
  	methods: {
      	reload() {
        this.isRouterAlive = false;
        this.$nextTick(function () {
            this.isRouterAlive = true;
        });
      }
  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

再就是到需要动态刷新数据的vue页面中添加代码,我这里叫answerquestion.vue页面
需要刷新的地方是在点击删除按钮成功删除数据后立即刷新table的数据,首先在该页面的js代码里写一个inject来注入App.vue页面的reload方法,然后在删除数据的方法(我这里是handleDelete)里调用inject注入的reload方法即可。需要加带代码的地方我都写了注释方便大家定位。

<script>
    import api from '../main'
    export default {
        inject: ['reload'], //依赖注入
        name: "AnswerQuestion",
        data() {
            return {
                getQuestion: [{
                    id: '',
                    request_time: '',
                    student_name: '',
                    question: '',
                    answer: '',
                }],
                ideatitystatus: ''
            }
        },
        created() {
            const _this = this;
            this.ideatitystatus =sessionStorage.getItem("isteacher");
            if(this.ideatitystatus == 'teacher')
            {
                axios.get(api.url + '/mes/findAll').then(function (resp) {
                    _this.getQuestion = resp.data;
                });
            }
        },
        methods: {
            handleDelete(row) {
                const _this = this;
                this.$confirm('此操作将永久删除该留言且不可恢复, 是否继续?', '提示', {
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    type: 'warning'
                }).then(() => {
                    axios.delete(api.url + '/mes/deleteById/' + row.id).then(function (resp) {
                    });
                    this.$message({
                        type: 'success',
                        message: '删除成功!'
                    });
                    this.reload(); //调用注入的方法达到刷新router-view的目的
                    // window.location.reload();//页面刷新(需要替代的代码)
                }).catch(() => {
                    this.$message({
                        type: 'info',
                        message: '已取消删除'
                    });
                });
            }
        },
    }
</script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53

Sptingboot后端代码

添加一个刷新后404页面的重定向配置类
我是在自己床单config包(配置类都写在这里)下面加一个java配置类 类名ErrorConfigurar.java 代码如下:

import org.springframework.boot.web.server.ErrorPage;
import org.springframework.boot.web.server.ErrorPageRegistrar;
import org.springframework.boot.web.server.ErrorPageRegistry;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;

//404错误页面重定向
@Configuration
public class ErrorConfigurar implements ErrorPageRegistrar {

    @Override
    public void registerErrorPages(ErrorPageRegistry registry) {
        ErrorPage[] errorPages = new ErrorPage[1];
        errorPages[0] = new ErrorPage(HttpStatus.NOT_FOUND, "/index.html");
//        errorPages[1] = new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, "/500.html");

//        registry.addError(errorPages);
        registry.addErrorPages(errorPages);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

注意!
这里指定重定向的页面index.html,是存在resource/static/目录下的index.html主页,如果你没有static文件夹就创一个然后放需要重定向的页面即可,如果你想写一个自定义的404页面,也可以把对应的页面放在这个路径中,然后在配置类里指向即可。

-----------------------------------------------------------------------------------------------------------------分割线
问题总结分析

前段时间写了这个项目,前后端分离,前端考虑到是单页面应用 就用Vue写的,后端用SpringBoot写的。在开发模式下端口访问数据请求,页面刷新都无比正常,非常爽~,但是一放到生产环境把所有东西打成一个jar包部署后,只要页面逻辑代码里写了this.$router.get(0)或者location.reload刷新页面或者手动点击浏览器刷新的地方都会出现服务器请求404的报错(This application has no explicit mapping for /error, so you are seeing this as a fallback.),嗯,没错,这就是VUE,history模式下router跳转的坑,欢迎入坑。主要原因是因为vue-router跳转设置的路径不是项目里真实存在的物理路径,而是它自己底层处理后解析的专门路径。所以服务器刷新后url读的是真实路径就会找不到,就会造成404的错误。

网上有一种解决方案就是改成默认的hash模式能解决问题,但是url里面就会加上#破坏url的美感,话说回来,我为什么要用history模式, 利用html5 新增的 history.pushState API 来完成 URL 跳转而无须重新加载页面,这样做的好处就是它提供了对历史记录进行修改的功能。只是当它们执行修改时,虽然改变了当前的 URL,但浏览器不会立即向后端发送请求, 也能用浏览器的前进后退,并且URL的显示更像正常的url。

改为hash后,但是这么做你url中就加了#,并且你有需要抓取url的地方还要截掉#得不偿失啊。一朝回到解放前了???不!她太丑了,这不是我想要的啊。我就要history。

又在网上看了好多解决方案,大体总结无非就几招,在404页面产生时在后端写个配置类处理掉404页面,给个指定的自定义跳转页,只要404发送就往指定的页面跳转,就看不到404了,一般都是让跳到首页即可。但是这样只解决了问题的一半。确实报错时立刻捕捉跳走了,那我页面数据变动时,数据刷新怎么办,你给我强制跳转处理掉了404页面,但数据就不刷新了呀,这两个功能居然是对立的,真的只能这样吗?不,我不妥协~。

关于动态数据刷新的问题,网上看到的解决方案也是挺傻瓜的,因为你直接写router.push指向当前页面它是不刷新也不跳转的。所以就再写一个VUE空页面给这个页面做刷新数据后的跳转页过度,然后在跳转页再写一个router.replace跳回来。这样一来一回确实很快感觉不到跳转,数据也刷新了。但总觉得哪里怪怪的,说不出来。

于是乎我又选择了另一个解决方案,用vue的provide加inject注入的方式给router-view加一个v-if判断,在状态改变的vue页面import注入的方法,再数据改变操作的代码处加reload刷新方法刷新router-view达到刷新数据的目的,实际得力于routerview在v-if真假判断后会刷新绑定的数据,重新加载达到刷新的目的,而且你的数据刷新页面也是在router-view中加载。这样好像还挺好的。那那那我就这么干吧,但是美中不足的地方就是开发者调试工具中的network还是会报红提示404的错误,虽然被后台截获处理掉了。

大致就这么磕磕碰碰的解决了这个问题,虽然不完美,如果我说的有不对的地方欢迎大家留言批评指正,或者提供更好的方法,让我们共同进步,谢谢!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/619357
推荐阅读
相关标签
  

闽ICP备14008679号