SpringBoot+Vue2 History路由模式去掉路径中的#

问题场景

1、前端vue项目想去掉 http://localhost:9080/dzjz/fljdyypt#/home中的#

2、vue打包后放在jar包部署

3、contextPath: /dzjz

4、想要不更改contextPath的情况下实现用 ip:port/dzjz/fljdyypt/xxx 方式访问

5、index.html放在templates里面了

前置知识

vue路由模式

hash(默认)

1、URL标识中的 '#' 和 后面URL片段标识符,被称为 hash

2、第一个 '#' 后面所有字符,浏览器会识别成为位置标识符,只用来标识页面的位置,这些字符都不会发送给服务器

3、单改变#后面的字符,浏览器只会锚点到相应的位置,不会重新加载url去加载新网页

4、底层原理通过window.addEventListener("hashchange", fun) 监听hash,去更新视图

history

1、url中没有#

2、window.history 提供了两类API:

  1. 跳到某个浏览记录:back(), forward(), go(),
  2. 添加/修改历史记录:pushState(), replaceState()

3、也是通过window.addEventListener('popstate', fun); 监听url改变,通过调用pushState(),replaceState()来修改当前的url,但是这种调用api的修改只会更新视图,不会向服务器发请求

4、当手动修改url地址并访问或者刷新页面,这种方式修改url访问请求会直接发送到服务器,比如我直接访问http://localhost:9080/dzjz/fljdyypt/home中,如果服务器没有配置对应的视图或者静态资源,那么就会404

springboot 静态资源

static
  1. 存放静态资源 css js 图片等
  2. 只要静态资源放在类路径下叫做/static、/public、/resources、 /META-INF/resources 就可以用 当前项目根路径/ + 静态资源名
  3. 请求进来,先找Controller,不能处理的交给静态资源处理器。静态资源也找不到->响应404页面
template
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

模板文件夹,该文件下的页面不能通过地址栏地址直接访问,需要经过Controller类来访问

如果你的index.html是放在这里的

resources
    -templates
        -index.html
@Controller
public class IndexController {

    @RequestMapping("/index")
    public String index(){
        // 这两种都可以
        return "index.html"; 
        // return "index" 
    }
}

如果目录是这样放置的

resources
    -templates
        -xxxx
            -index.html
@Controller
public class IndexController {

    @RequestMapping("/index")
    public String index(){
        // 这两种都可以
        return "xxxx/index.html"; 
        // return "xxxx/index" 
    }
}

解决步骤

更改路由配置

1、mode:路由模式

2、base:

  • 就是你路由切换时url中 不变的那部分啦
  • 如果你配置了contextPath那么 dzjz是一定不能少的
  • fljdyypt也不能少,要不然刷新之后 url就只剩http://localhost:9080/dzjz/home了(不符合问题场景第4条需求)
const router = new VueRouter({
  routes,
  mode:'history',
  base: '/dzjz/fljdyypt'
})

修改前端打包配置

module.exports = {
    publicPath: '/dzjz/fljdyypt',
  // 所有的东西都在dist里面
}


// 或者
module.exports = {
    publicPath: '/dzjz',
    assetsDir: 'fljdyypt',
  //  js、css、fonts、img在fljdyypt里面  .ico和index.html直接在dist下
}

这样打包完index.html 里面就变成这种了, 你的index.html 就会找到对应的的js、css等

<link href="/dzjz/fljdyypt/css/index.1b92b919.css" rel="stylesheet">

问: 你publicPath设置成 '' 或者用'dzjz' 之类的 用相对路径行不行呢? 我试了不行 不知道是我配置有问题还是咋的, 咱先回避下这个问,先保证功能好用

前端打包

npm run build

后端创建静态资源目录,并把dist的东西分类往里面塞

后端设置下resources 创建目录并 把dist打包后对应的文件放里面

-resources
    -static
        -fljdyypt
            -css
            -fonts
            -img
            -js
        -favicon.ico
    -templates
        -index.html

配置404转发

由于history模式下,手动修改url或者手动刷新页面,请求会直接发到服务器 ,比如http://localhost:9080/dzjz/fljdyypt/home

1、先找controller看看有没有对应的视图解析

2、再找静态资源有没有这个东东

都没有肯定404啦 路由变化就交给前端处理 所以要转发到http://localhost:9080/dzjz/fljdyypt/ 交给下一步的视图解析处理

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;

@Configuration
public class HistoryConfig implements ErrorPageRegistrar {

    @Override
    public void registerErrorPages(ErrorPageRegistry errorPageRegistry) {
        ErrorPage errorPage = new ErrorPage(HttpStatus.NOT_FOUND, "/fljdyypt");
        errorPageRegistry.addErrorPages(errorPage);
    }
}

配置视图解析

由于fljdyypt 不是contextPath 所有我们要手动写一个 controller

@Controller
public class IndexController {

    @RequestMapping("/fljdyypt")
    public String aIndex(){
        return "index.html";
    }
    
}

至此大功告成

总结

我这个需求有点麻烦奥(比如不想改contextPath、前后端不分离部署 有点反人类),如果你的项目只有contexPath,那么只需

1、改个路由配置

2、改个前端打包配置

3、配个404转发

期待批评指正

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值