reactjs - 配置 CORSin spring boot 和 reactjs 的问题

在阅读了 CORS 上的所有 MDN 文档后,我试图从 localhost:3000 的 ReactJS 应用程序在 localhost:8080 的 spring boot 服务器上获取资源,但我无法获得所需的响应。这是 spring boot 配置

...
 @Override
  protected void configure(HttpSecurity http) throws Exception {
      
    http.cors();
    
    http.authorizeRequests().antMatchers(
        // "/registration**",
        "/js/**", "/css/**", "/img/**", "/api/**", "/webjars/**").permitAll()
        .antMatchers("/calendar", "/calendar-delete", "/calendar-edit", "/calendar-addEvent",
            "/calendar-updateEvent", "/contacts", "/contact-edit", "/jobs/jobs-list", "/job-new",
            "/applicants/applicants-list", "/applicant-new", "/", "/index", "/task-list", "/task-assign",
            "/tasks-pending", "/task-approve", "/task-deny", "/profile", "/upload-avatar", "/users",
            "/settings", "/appsettings", "/changepassword", "/messages", "/message", "/message-new",
            "/message-to", "/h2-console/**")
        .permitAll().antMatchers("/admin/**")
        .hasAuthority("ROLE_ADMIN").antMatchers("/activites/**")
        .hasAnyAuthority("ROLE_ADMIN","ROLE_COLLABORATEUR").and().formLogin().loginProcessingUrl("/api/login").permitAll()
        .and()
        .formLogin().failureHandler(customAuthenticationFailureHandler())
        .and().formLogin().successHandler(successHandler())
        .and()
        .logout()
        .invalidateHttpSession(true).clearAuthentication(true)
        .logoutRequestMatcher(new AntPathRequestMatcher("/logout")).logoutSuccessUrl("/login?logout")
        .permitAll();
    
    http.csrf().disable();
    
  }

@Bean
  public CustomSuccessHandler successHandler() {
      return new CustomSuccessHandler();
  }
....
 @Bean
  public CorsConfigurationSource corsConfigurationSource() {
    CorsConfiguration configuration = new CorsConfiguration();
    
    configuration.setAllowedOrigins(Arrays.asList("*"));    
    configuration.setAllowedMethods(Arrays.asList("GET","POST"));
    configuration.addAllowedHeader("*");
    configuration.setAllowCredentials(false);
    
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/**", configuration);
    return source;
  }

这是负责处理请求的控制器方法

@GetMapping("/api/plot")
    @ResponseBody
    public List<StatisticBesoin> plot(@RequestParam("date") int year) {
        return this.besoinService.getStatistic(year);
    }

这是 Reactjs 登录组件,请注意,按下登录按钮后,我会收到所需的 json 响应和 set-cookies jssid

const Login = (props) => {
    const navig = useNavigate();

    const [userName,setUserName] = useState("");
    const [password,setPassword] = useState("");

    function authenticate(usr,pswrd){
        var data = new URLSearchParams();
        
        data.append('username', usr);
        data.append('password', pswrd);
        
        fetch("http://localhost:8080/api/login",{
            headers:{
                "Content-type": "application/x-www-form-urlencoded",
            },
            method:"post",
            body:data
        }).then(response => response.json()).then(usr => {props.setUser(usr);console.log(usr);navig('/homme')});
    }

    return(
        <div className='wrapper'>
            <div className='login'>
                <div className='header'>Login</div>
                <div className="form-control"><i className="fa fa-user" aria-hidden="true"></i><input onChange={(e)=>setUserName(e.target.value)} name="userName" id="userName" type="text" placeholder="User name" /></div>
                <div className="form-control"><i className="fa fa-lock" aria-hidden="true"></i><input onChange={(e)=>setPassword(e.target.value)} name="userName" id="userPassword" type="password" placeholder="Password" /></div>
                <div className="form-control"><input type="button" value="Login" onClick={()=>authenticate(userName,password)}/></div>
            </div>
        </div>
    )
}

在我的问题所在的主页旁边:

const Home = (props) => {

    function plot(){
        fetch('http://localhost:8080/api/plot')
        .then(resp => resp)
        .then(t => {console.log(t)})}

    return(
        <div className='wrapper'>
            <input type="button" value="call" onClick={plot}/>
            {props.usr.toString()}
        </div>
    )
}

按下按钮后的反应是ò

body: (...)
bodyUsed: false
headers: Headers
[[Prototype]]: Headers
ok: true
redirected: true
status: 200
statusText: "OK"
type: "cors"
url: "http://localhost:8080/login"

我尝试了从将允许的来源设置为“*”到将请求中的 allow-credentials 标头设置为“包含”的所有方法,但都是徒劳的。请注意,我可以看到与 /plot 请求一起发送的 jssid cookie,所以我想我的身份验证没有问题。有人可以找出问题所在吗?我认为问题的所有资源都可用,但如果需要我会提供任何其他资源?

回答1

如果这是一个本地开发环境,通过使用以下属性增强您的 React 应用程序 package.json 来启用 https://create-react-app.dev/docs/proxying-api-requests-in-development/ 的代理功能通常就足够了:

"proxy": "http://localhost:8080"

然后,将您的 Ajax 请求从您的 React 应用程序发送到 /your/api/path 而不是 http://localhost:8080/your/api/path 并且开发网络服务器会将 Ajax 请求代理到提供的地址,并且您的浏览器不会抱怨 CORS。

您不需要在 Spring 引导应用程序中配置任何特定的 CORS 支持。

稍后,当应用程序部署在 web 服务器上时,这通常不再是问题,因为两者都将在同一主机上提供服务,然后 Ajax 请求由主机上的 web 服务器代理到后端,该服务器为入站请求提供服务。

相似文章

随机推荐

最新文章