首页 > 解决方案 > 在 Heroku .Cors 中部署 Vue.js+Spring Boot +Graddle 应用程序时出错。没有“Access-Control-Allow-Origin”错误

问题描述

美好的一天开发人员我真的在为这个应用程序及其部署而苦苦挣扎。简而言之,我已经在 Heroku 中部署了所有后端,并且一直在尝试测试它如何与我的 Vue.Js 前端连接,但是关于 CORS 的一个问题是我无法到达那里错误是:

Access to fetch at 'my url/scorepoll' from origin 'http://localhost:8080' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

我的引用 CORS 和安全 Web 服务的后端配置被配置为:

package com.example.demo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.authentication.configuration.GlobalAuthenticationConfigurerAdapter;
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.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.WebAttributes;
import org.springframework.security.web.authentication.logout.HttpStatusReturningLogoutSuccessHandler;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.Arrays;
import java.util.Date;


@SpringBootApplication
public class CrabApplication {

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

    @Bean
    public PasswordEncoder passwordEncoder() {
        return PasswordEncoderFactories.createDelegatingPasswordEncoder();
    }
}

@Configuration
@EnableWebSecurity
class WebSecurityConfiguration extends GlobalAuthenticationConfigurerAdapter {
    @Autowired
    PlayerCrabRepository playerCrabRepository;

    @Override
    public void init(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(inputName -> {
            PlayerCrab playerCrab = playerCrabRepository.findByUserName(inputName);
            if (playerCrab != null) {
                return new User(playerCrab.getuserName(), playerCrab.getUserPassword(),
                        AuthorityUtils.createAuthorityList("USER"));
            } else {
                throw new UsernameNotFoundException("Unknown user: " + inputName);
            }
        });
    }
}

@Configuration
@EnableWebSecurity
class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.cors();
        http.authorizeRequests()
                .antMatchers("/crabs/game/all").permitAll()
                .antMatchers("/crabs/game/register").permitAll()
                .antMatchers("/crabs/game/{gameCrabId}").permitAll()
                .antMatchers("crabs/game/play/{gameDiceId}").permitAll()
                .antMatchers("/crabs/game/scorepoll").permitAll()
                .antMatchers("/crabs/game/create").permitAll()
                .antMatchers("/crabs/game/allshots").permitAll()

                .antMatchers("/h2-console/**").permitAll()
                .antMatchers("/rest/**").hasAuthority("ADMIN")

                .antMatchers("/**").hasAuthority("USER")
                .anyRequest().fullyAuthenticated();

        http.formLogin()
                .usernameParameter("userName")
                .passwordParameter("userPassword")
                .loginPage("/crabs/game/login");

        http.logout().logoutUrl("/crabs/game/logout");

        http.csrf().disable();

        http.exceptionHandling().authenticationEntryPoint((req, res, exc) -> res.sendError(HttpServletResponse.SC_UNAUTHORIZED));

        http.formLogin().successHandler((req, res, auth) -> clearAuthenticationAttributes(req));

        http.formLogin().failureHandler((req, res, exc) -> res.sendError(HttpServletResponse.SC_UNAUTHORIZED));

        http.logout().logoutSuccessHandler(new HttpStatusReturningLogoutSuccessHandler());

        http.headers().frameOptions().sameOrigin();
    }

    private void clearAuthenticationAttributes(HttpServletRequest request) {
        HttpSession session = request.getSession(false);
        if (session != null) {
            session.removeAttribute(WebAttributes.AUTHENTICATION_EXCEPTION);
        }
    }

    @Bean////importando Heroku a la base de datos
    public CorsConfigurationSource corsConfigurationSource() {
        final CorsConfiguration configuration = new CorsConfiguration();
       
        configuration.setAllowedOrigins(Arrays.asList("*"));
        configuration.setAllowedMethods(Arrays.asList("HEAD",
                "GET", "POST", "PUT", "DELETE", "PATCH"));
       
        configuration.setAllowCredentials(true);
        configuration.addAllowedOrigin("*");
        configuration.addAllowedHeader("*");
        configuration.addAllowedMethod("*");

       
        configuration.setAllowedHeaders(Arrays.asList("Authorization", "Cache-Control", "Content-Type",
                "Accept","Access-Control-Request-Method","Access-Control-Request-Headers","Access-Control-Allow-Origin",
                "Accept-Language","Authorization","Content-Type","Request-Name","Request-Surname","Origin","X-Request-AppVersion",
                "X-Request-OsVersion", "X-Request-Device", "X-Requested-With"));
        final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }
}

在特定的 fetch 错误触发器中,在本地总是与 time 设置的标头一起正常工作:

const url="http://myherokuapp...."

scorePlayer({ commit }) {
      return fetch(url + "/crabs/game/scorepoll", {
        credentials: "include",
        headers: {
          "Content-Type": "application/x-www-form-urlencoded",
        },
        method: "GET",
      })
        .then((response) => {
         
          return response.json();
        })
        .then((response) => {
         
          return response, commit("setScorePlayer", response);
        })
        .catch((error) => {error
          
        });
    },

甚至,作为测试,在我的 cors 配置中,我设置了请求的来源(我的本地主机前端),以查看是否是问题所在)

....
@Bean////importando Heroku a la base de datos
    public CorsConfigurationSource corsConfigurationSource() {
        final CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(Arrays.asList("http://localhost:8080"));====HERE
        configuration.setAllowedMethods(Arrays.asList("HEAD",
                "GET", "POST", "PUT", "DELETE", "PATCH"));

但是没有用。

因此我有点迷路和困惑。我的第一个应用程序是否试图将其部署在 Heroku 上,我真的很难过。任何建议都会很棒。谢谢!!!

标签: spring-bootvue.jsherokudeploymentcors

解决方案


Spring Boot 将阻止来自不同来源的所有请求,因此您的所有请求都被阻止。

通过这个的方法

  1. 在您的 Vue.js 中添加代理以避免 -首选方式
  2. 在控制器上使用@CrossOrigin("your-origin")
  3. 实现一个 Spring Boot 过滤器,它将拦截请求并在您的请求中添加“Access-Control-Allow-Origin”标头

推荐阅读