Angular+Spring Boot打包单WAR部署后页面刷新报403错误如何解决
问题根因
你遇到的403问题核心是Angular默认使用HTML5路由模式(无#号的前端路由),运行逻辑是:
- 首次访问根路径
/时,你写的/接口会转发到/ui/index.html,Angular加载完成后由前端路由负责跳转页面,全程不触发后端新请求,所以运行正常 - 刷新页面时,浏览器会把当前完整的前端路由路径(比如
/ui/user/manage)直接发送给后端请求,你的后端static目录下不存在对应路径的静态资源,该请求无法匹配到静态资源也匹配不到你写的接口,最终落入HttpSecurity配置的anyRequest().authenticated()权限校验规则,因为请求没带身份凭证就返回403。
解决方案
方案1:后端配置路由转发(推荐,URL无#更友好)
总共需要修改2处配置:
- 新增WebMvc配置,将所有/ui/开头的非静态资源请求转发到Angular入口
import org.springframework.context.annotation.Configuration; import org.springframework.core.Ordered; import org.springframework.core.io.Resource; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.resource.PathResourceResolver; import java.io.IOException; @Configuration public class WebMvcConfig implements WebMvcConfigurer { @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/ui/**") .addResourceLocations("classpath:/static/ui/") .resourceChain(true) .addResolver(new PathResourceResolver() { @Override protected Resource getResource(String resourcePath, Resource location) throws IOException { Resource requestedResource = location.createRelative(resourcePath); // 资源存在直接返回,不存在就返回index.html让Angular处理路由 return requestedResource.exists() && requestedResource.isReadable() ? requestedResource : location.createRelative("index.html"); } }); } @Override public void addViewControllers(ViewControllerRegistry registry) { // 根路径直接转发到Angular入口,可以删除你之前写的@GetMapping("/")接口 registry.addViewController("/").setViewName("forward:/ui/index.html"); registry.setOrder(Ordered.HIGHEST_PRECEDENCE); } }
你现有的Spring Security配置不需要改动,web.ignoring().antMatchers("/ui/**")已经放行所有/ui开头的请求,不会触发权限校验。
方案2:前端改用Hash路由模式(无需改后端,快速生效)
如果接受URL带#号,直接修改Angular的路由配置即可,刷新时#后的路由内容不会发送到后端,不会触发403:
在Angular项目的app-routing.module.ts里修改providers配置:
import { NgModule } from '@angular/core'; import { RouterModule, Routes, HashLocationStrategy, LocationStrategy } from '@angular/router'; const routes: Routes = [/* 保留你的原有路由规则 */]; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule], providers: [{ provide: LocationStrategy, useClass: HashLocationStrategy }] }) export class AppRoutingModule { }
修改后重新执行ng build --prod --base-href=/ui/ --deploy-url=/ui/打包替换静态资源即可生效。
内容的提问来源于stack exchange,提问作者Payal
相关产品推荐
相关产品推荐

