자바 는 어떻게 크로스 필드 문 제 를 해결 합 니까?

머리말
우 리 는 개발 과정 에서 앞 뒤 가 분리 되 어 발생 하 는 크로스 오 버 문 제 를 자주 만 나 결 과 를 얻 지 못 한다.도 메 인 을 넘 는 것 은 전단 과 백 엔 드 를 분리 하 는 큰 갭 과 같 습 니 다.군 주 는 이쪽 에 있 고 그녀 는 저쪽 에 있 습 니 다.두 사람 은 왕래 할 수 없습니다.
크로스 도 메 인(CORS)이란 무엇 입 니까?
크로스 도 메 인(CORS)은 도 메 인 이름 간 에 서로 접근 하 는 것 을 말한다.도 메 인 을 뛰 어 넘 는 것 은 브 라 우 저가 다른 사이트 의 스 크 립 트 를 실행 할 수 없 는 것 을 말 합 니 다.브 라 우 저의 같은 소스 정책 으로 인해 발생 한 것 으로 브 라 우 저가 자바 스 크 립 트 에 대해 정의 하 는 보안 제한 정책 입 니 다.
어떤 상황 이 도 메 인 을 뛰 어 넘 습 니까?
  • 같은 협의,예 를 들 어 http 또는 https
  • 같은 IP 주소,예 를 들 어 127.0.0.1
  • 같은 포트,예 를 들 어 8080
  • 상기 세 가지 조건 중 한 가지 조건 이 다 르 면 크로스 필드 문제 가 발생 할 수 있다.
    해결 방안
    전단 해결 방안
  • JSONP 방식 으로 크로스 도 메 인 호출 을 실현 합 니 다.
  • NodeJS 서버 를 서비스 에이전트 로 사용 하고 전단 에서 NodeJS 서버 에 요청 하 며 NodeJS 서버 프 록 시 에서 백 엔 드 서버 에 전송 요청 합 니 다.
  • 백 엔 드 솔 루 션
  • nginx 역방향 대리 해결 크로스 도 메 인
  • 서버 에서 Response Header(응답 헤드)를 설정 한 Access-Control-Allow-Origin
  • 크로스 도 메 인 접근 이 필요 한 클래스 와 방법 에 크로스 도 메 인 접근 을 허용 하도록 설정 합 니 다(예 를 들 어 Spring 에서@CrossOrigin 주 해 를 사용 합 니 다).
  • Spring Web 을 사용 하 는 CorsFilter(Spring MVC,Spring Boot 에 적용)
  • 계승
  • WebMvcConfigurer 인터페이스 실현(Spring Boot 에 적용)
  • 구체 적 인 방식
    1.Filter 방식 으로 설정
    필터 필 터 를 사용 하여 서비스 요청 을 걸 러 내 고 요청 단 에 Response Header(응답 머리)의 Access-Control-Allow-Origin 속성 설명 을 설정 하여 도 메 인 접근 을 허용 합 니 다.
    
    @WebFilter
    public class CorsFilter implements Filter { 
    
      @Override
      public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { 
        HttpServletResponse response = (HttpServletResponse) res; 
        response.setHeader("Access-Control-Allow-Origin", "*"); 
        response.setHeader("Access-Control-Allow-Methods", "*"); 
        response.setHeader("Access-Control-Max-Age", "3600"); 
        response.setHeader("Access-Control-Allow-Headers", "*");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        chain.doFilter(req, res); 
      } 
    }
    2.HandlerInterceptorAdapter 계승
    
    @Component
    public class CrossInterceptor extends HandlerInterceptorAdapter {
    
      @Override
      public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "*");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        return true;
      }
    }
    3.WebMvcConfigurer 실현
    
    @Configuration
    @SuppressWarnings("SpringJavaAutowiredFieldsWarningInspection")
    public class AppConfig implements WebMvcConfigurer {
    
      @Override
      public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**") //        
            .allowedOrigins("http://www.abc.com") //       ,    *
            .allowCredentials(true)
            .allowedMethods("*")  //        ,      
            .allowedHeaders("*"); //         ,      
      }
    }
    
    4.Nginx 설정 사용
    
    location / {
      add_header Access-Control-Allow-Origin *;
      add_header Access-Control-Allow-Headers X-Requested-With;
      add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,OPTIONS;
    
      if ($request_method = 'OPTIONS') {
       return 204;
      }
    }
    5.@CrossOrgin 주석 사용
    일부 인터페이스 크로스 필드 만 원 하고 설정 으로 관리 하고 싶 지 않다 면 이 방식 을 사용 할 수 있 습 니 다.
    Controller 에서 사용
    
    @CrossOrigin
    @RestController
    @RequestMapping("/user")
    public class UserController {
    
    	@GetMapping("/{id}")
    	public User get(@PathVariable Long id) {
    		
    	}
    
    	@DeleteMapping("/{id}")
    	public void remove(@PathVariable Long id) {
    
    	}
    }
    구체 적 인 인터페이스 에서 사용 하 다
    
    @RestController
    @RequestMapping("/user")
    public class UserController {
    
    	@CrossOrigin
    	@GetMapping("/{id}")
    	public User get(@PathVariable Long id) {
    		
    	}
    
    	@DeleteMapping("/{id}")
    	public void remove(@PathVariable Long id) {
    
    	}
    }
    Spring Cloud Gateway 크로스 도 메 인 설정
    
    spring: 
     cloud:
      gateway:
       globalcors:
        cors-configurations:
         '[/**]':
          #       (    /ip),  *   
          #         head  ,  *   
          #      method,    GET OPTIONS,  *   
          allow-credentials: true
          allowed-origins:
           - "http://xb.abc.com"
           - "http://sf.xx.com"
          allowed-headers: "*"
          allowed-methods:
           - OPTIONS
           - GET
           - POST
           - DELETE
           - PUT
           - PATCH
          max-age: 3600
    메모:gateway을 통 해 전 송 된 다른 항목 은 전역 설정 을 하지 마 십시오.
    설정 되 어 있어 도 작 동 하지 않 을 때 가 있 습 니 다.이 때 는 브 라 우 저 제어 오류 에 따라 문 제 를 볼 수 있 습 니 다.힌트 가response에서 header 중복 되 는 Access-Control-*요청 헤드 가 나타 나 면 다음 과 같은 작업 을 할 수 있 습 니 다.
    
    import java.util.ArrayList;
    import org.springframework.cloud.gateway.filter.GatewayFilterChain;
    import org.springframework.cloud.gateway.filter.GlobalFilter;
    import org.springframework.cloud.gateway.filter.NettyWriteResponseFilter;
    import org.springframework.core.Ordered;
    import org.springframework.http.HttpHeaders;
    import org.springframework.stereotype.Component;
    import org.springframework.web.server.ServerWebExchange;
    import reactor.core.publisher.Mono;
    
    @Component("corsResponseHeaderFilter")
    public class CorsResponseHeaderFilter implements GlobalFilter, Ordered {
    
     @Override
     public int getOrder() {
      //         NettyWriteResponseFilter  
      //                 
      return NettyWriteResponseFilter.WRITE_RESPONSE_FILTER_ORDER + 1;
     }
    
     @Override
     public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
      return chain.filter(exchange).then(Mono.defer(() -> {
       exchange.getResponse().getHeaders().entrySet().stream()
         .filter(kv -> (kv.getValue() != null && kv.getValue().size() > 1))
         .filter(kv -> (
           kv.getKey().equals(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN)
             || kv.getKey().equals(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS)
             || kv.getKey().equals(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS)
             || kv.getKey().equals(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS)
             || kv.getKey().equals(HttpHeaders.ACCESS_CONTROL_MAX_AGE)))
         .forEach(kv -> {
          kv.setValue(new ArrayList<String>() {{
           add(kv.getValue().get(0));
          }});
         });
       return chain.filter(exchange);
      }));
     }
    }
    이상 은 자바 가 도 메 인 문 제 를 어떻게 해결 하 는 지 에 대한 상세 한 내용 입 니 다.자바 가 도 메 인 문 제 를 해결 하 는 데 관 한 자 료 는 우리 의 다른 관련 글 에 관심 을 가 져 주 십시오!

    좋은 웹페이지 즐겨찾기