带有 Angular + Springboot 的 Whitelabel 错误页面

Posted

技术标签:

【中文标题】带有 Angular + Springboot 的 Whitelabel 错误页面【英文标题】:Whitelabel Error Page with Angular + Springboot 【发布时间】:2020-09-22 18:48:38 【问题描述】:

每当我尝试在我的 Angular 9 应用程序上加载任何页面(根路由除外)时,我都会收到一个 Whitelabel 错误页面(错误 404),方法是将 URL 放在浏览器上并按 Enter 键或刷新页面。使用页面按钮(Angular 路由器)加载这些页面效果很好。

我尝试了许多来自 *** 的解决方案来解决这个问题,但都没有奏效。

whitelabel error page

后端主类

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class GroupsApplication 

    public static void main(String[] args) 
        SpringApplication.run(WarcraftgroupsApplication.class, args);
    


后端安全配置器

import com.sampaiodias.groups.auth.filters.JwtRequestFilter;
import com.sampaiodias.groups.auth.services.MyUserDetailsService;
import org.springframework.context.annotation.Bean;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

@EnableWebSecurity
public class SecurityConfigurer extends WebSecurityConfigurerAdapter 

    private final MyUserDetailsService myUserDetailsService;
    private final JwtRequestFilter jwtRequestFilter;

    public SecurityConfigurer(MyUserDetailsService myUserDetailsService, JwtRequestFilter jwtRequestFilter) 
        this.myUserDetailsService = myUserDetailsService;
        this.jwtRequestFilter = jwtRequestFilter;
    

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception 
        auth.userDetailsService(myUserDetailsService);
    

    @Override
    protected void configure(HttpSecurity http) throws Exception 
        http.csrf().disable().authorizeRequests().antMatchers("/auth", "/user", "/refresh", "/end-session").permitAll()
                .and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
        http.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
    

    @Bean
    public PasswordEncoder passwordEncoder() 
        return NoOpPasswordEncoder.getInstance();
    

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception 
        return super.authenticationManagerBean();
    


前端应用路由模块

import  GroupsComponent  from './groups/groups/groups.component';
import  RegisterComponent  from './auth/register/register.component';
import  LoginComponent  from './auth/login/login.component';
import  AppComponent  from './app.component';
import  NgModule  from '@angular/core';
import  Routes, RouterModule  from '@angular/router';

const routes: Routes = [
  
    path: '',
    component: AppComponent,
  ,
  
    path: 'login',
    component: LoginComponent,
  ,
  
    path: 'register',
    component: RegisterComponent,
  ,
  
    path: 'groups',
    component: GroupsComponent,
  ,
   path: '**', redirectTo: '/' ,
];

@NgModule(
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule],
)
export class AppRoutingModule 

前端代理

const PROXY_CONFIG = [
  
    context: ["/", "/user", "/group", "/character"],
    target: "http://localhost:8080",
    secure: false,
  ,
];

module.exports = PROXY_CONFIG;

【问题讨论】:

【参考方案1】:

您必须为您在路由模块中设置的每条 Angular 路由转发到 index.html,而不仅仅是根路由。请参阅Spring Boot with redirecting with single page angular2 定义单个控制器以将所有请求转发到 index.html。

否则 Spring 会尝试自己处理 url,但由于它没有您输入的 url 的 @Controller 请求映射(因为您希望 Angular 处理它),它返回 404。

编辑

OP 指的是ng serve,而不是已部署的环境。在这种情况下,您必须创建一个重定向到 ng 开发服务器的 ErrorController - http://localhost:4200

@Controller
@RequestMapping("$server.error.path:$error.path:/error")
public class AngularRedirectErrorController extends AbstractErrorController 

  private final ErrorAttributes errorAttributes;

  public AngularRedirectErrorController(ErrorAttributes errorAttributes) 
    super(errorAttributes);
    this.errorAttributes = errorAttributes;
  

  @RequestMapping(produces = MediaType.TEXT_HTML_VALUE)
  public String redirectToAngular(ServletWebRequest request) 
    Map<String, Object> errorAttrs = errorAttributes.getErrorAttributes(request, false);
    String path = (String) errorAttrs.get("path");
    return "redirect:http://localhost:4200" + path;
  

  @RequestMapping(produces = MediaType.APPLICATION_JSON_VALUE)
  @ResponseBody
  public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) 
    HttpStatus status = getStatus(request);
    if (status == HttpStatus.NO_CONTENT) 
        return new ResponseEntity<>(status);
    

    WebRequest webRequest = new ServletWebRequest(request);
    Map<String, Object> body = errorAttributes.getErrorAttributes(webRequest, false);
    return new ResponseEntity<>(body, status);
  

  @Override
  public String getErrorPath() 
    return null;
  


【讨论】:

这对我不起作用,而不是白标签页面,我得到了一个完全白色的页面。如果我理解这背后的原因,当我在使用 ng serve 运行我的 Angular 应用程序时遇到此错误时,为什么要将我的 Angular 应用程序的构建放在 Spring 静态文件夹中? 哦,你在使用 ng serve!由于您没有提到这一点,我以为您指的是已部署的环境。请参阅我的更新答案。 它确实解决了可白标问题,谢谢!是否可以重定向到我尝试访问的页面而不仅仅是根路由?例如,如果我尝试访问localhost:4200/foo,上面的代码会将我重定向到localhost:4200 发布的解决方案实际上也破坏了我的 JWT 身份验证,当 JWT 令牌过期时(而不是返回 403 或 401)给出以下错误: core.js:6272 错误错误:未捕获(承诺): HttpErrorResponse: "headers":"normalizedNames":,"lazyUpdate":null,"status":200,"statusText":"OK","url":"localhost:4200/…@987654325 解析失败@":"error":,"text":"\n\n \n \n... 您的代码修复了 JWT 部分,非常感谢!但是,当涉及到重定向时,它不起作用,页面仍然无法加载。它调用 redirectToAngular 方法 20 次(返回正确的 url + 路径),但浏览器显示 ERR_TOO_MANY_REDIRECTS 错误。

以上是关于带有 Angular + Springboot 的 Whitelabel 错误页面的主要内容,如果未能解决你的问题,请参考以下文章

带有 Spring Boot 的 Angular CLI

带有 Keycloak 的 Angular/Spring Boot 抛出 403

带有Angular应用程序的tomcat 9服务器上的Spring Boot 404和CORS

寻找带有 Angular 4 和更多一个弹簧启动应用程序的示例 [关闭]

获取 JWT 后,带有 Spring Boot 后端的 Angular 在现有路由上返回 404

在带有 Angular 的 Spring Boot 中启用了 Cors,但仍然出现 cors 错误