本文由 简悦 SimpRead 转码, 原文地址 blog.csdn.net
问题场景
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:
- 跳到某个浏览记录:back(), forward(), go(),
- 添加 / 修改历史记录:pushState(), replaceState()
3、也是通过 window.addEventListener('popstate', fun); 监听 url 改变,通过调用 pushState(),replaceState() 来修改当前的 url,但是这种调用 api 的修改只会更新视图,不会向服务器发请求
4、当手动修改 url 地址并访问或者刷新页面,这种方式修改 url 访问请求会直接发送到服务器,比如我直接访问 http://localhost:9080/dzjz/fljdyypt/home 中,如果服务器没有配置对应的视图或者静态资源,那么就会 404
springboot 静态资源
static
- 存放静态资源 css js 图片等
- 只要静态资源放在类路径下叫做 / static、/public、/resources、 /META-INF/resources 就可以用 当前项目根路径 / + 静态资源名
- 请求进来,先找 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 等
-resources
-static
-fljdyypt
-css
-fonts
-img
-js
-favicon.ico
-templates
-index.html
问: 你 publicPath 设置成 ''或者用'dzjz' 之类的 用相对路径行不行呢? 我试了不行 不知道是我配置有问题还是咋的, 咱先回避下这个问,先保证功能好用
前端打包
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);
}
}
后端创建静态资源目录,并把 dist 的东西分类往里面塞
后端设置下 resources 创建目录并 把 dist 打包后对应的文件放里面
@Controller
public class IndexController {
@RequestMapping("/fljdyypt")
public String aIndex(){
return "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 转发
期待批评指正