Home  >  Article  >  Java  >  How Springboot solves the cross-domain request problem of ajax custom headers

How Springboot solves the cross-domain request problem of ajax custom headers

王林
王林forward
2023-05-16 12:43:061083browse

1. What is cross-domain

Due to the browser’s same-origin policy (same-origin policy), it is a well-known security policy proposed by Netscape. Now all browsers that support JavaScript All servers will use this strategy. The so-called same origin means that the domain name, protocol, and port are the same.). Any one of the protocol, domain name, and port used to send the request URL is different from the current page address, which is considered cross-domain.

For details, please check the following table:

How Springboot solves the cross-domain request problem of ajax custom headers

2. How springboot solves cross-domain problems

1. Ordinary cross-domain request solution:

①Add the annotation @CrossOrigin(origins = "http://127.0.0.1:8020", maxAge = 3600)

to the request interface Description: origins = "http://127.0.0.1:8020" The origins value is the domain currently requesting the interface

②General configuration (all interfaces allow cross-domain requests)

New A configuration class or add CorsFilter and CorsConfiguration methods in Application

@Configuration 
public class CorsConfig { 
  private CorsConfiguration buildConfig() { 
    CorsConfiguration corsConfiguration = new CorsConfiguration(); 
    corsConfiguration.addAllowedOrigin("*"); // 1允许任何域名使用
    corsConfiguration.addAllowedHeader("*"); // 2允许任何头
    corsConfiguration.addAllowedMethod("*"); // 3允许任何方法(post、get等) 
    return corsConfiguration; 
  } 

  @Bean 
  public CorsFilter corsFilter() { 
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); 
    source.registerCorsConfiguration("/**", buildConfig()); // 4 
    return new CorsFilter(source); 
  } 
}

2. Cross-domain request of ajax custom headers

$.ajax({
    type:"GET",
    url:"http://localhost:8766/main/currency/sginInState",
    dataType:"JSON",
    data:{
      uid:userId
    },
    beforeSend: function (XMLHttpRequest) {
      XMLHttpRequest.setRequestHeader("Authorization", access_token);
    },
    success:function(res){
      console.log(res.code)
    }
  })

Request http at this time: The //localhost:8766/main/currency/sginInState interface found an OPTIONS http://localhost:8766/main/currency/sginInState 500 error. Ordinary cross-domain solutions cannot solve this problem. Why does an OPTIONS request appear?

How Springboot solves the cross-domain request problem of ajax custom headers

Reason

The browser will send a preflight request with method OPTIONS before sending the actual request. Preflighted requests This The request is used to verify whether this request is safe, but not all requests will be sent and need to meet the following conditions:

•The request method is not GET/HEAD/POST
•Content-Type of the POST request Not application/x-www-form-urlencoded, multipart/form-data, or text/plain

•The request sets a custom header field

For the management interface, I have the The interface performs permission verification. Each request needs to carry a custom field (token) in the header, so the browser will send an additional OPTIONS request to verify the security of this request.

Why is the OPTIONS request 500?

OPTIONS request will only carry custom fields and will not bring the corresponding values ​​in. When the token field is verified in the background, the token is NULL, so the verification fails and a abnormal.

So let’s solve this problem now:

① Add

spring:
to the spring boot project application.yml mvc:
dispatch-options-request: true

Note: This solution may not solve the OPTIONS problem in some cases. The reason may be environmental issues or complex Custom filter filter configuration issues, etc.

②Add filter configuration

Step 1: Handwritten RequestFilter request filter configuration class This class needs to implement the HandlerInterceptor class, which is under org.springframework.web.servlet.HandlerInterceptor.

Specific code implementation:

@Component
public class RequestFilter implements HandlerInterceptor {
  public boolean preHandler(HttpServletRequest request,HttpServletResponse response,Object handler){
    response.setHeader("Access-Control-Allow-Origin", "*");
    response.setHeader("Access-Control-Allow-Credentials", "true");
    response.setHeader("Access-Control-Allow-Methods", "GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS");
    response.setHeader("Access-Control-Max-Age", "86400");
    response.setHeader("Access-Control-Allow-Headers", "Authorization");
    // 如果是OPTIONS请求则结束
    if (HttpMethod.OPTIONS.toString().equals(request.getMethod())) {
      response.setStatus(HttpStatus.NO_CONTENT.value());
      return false;
    }
    return true;
  }
}

Step 2: Handwriting MyWebConfiguration This class needs to inherit WebMvcConfigurationSupport.

Note: WebMvcConfigurationSupport is version 2.x or above, and version 1.x is WebMvcConfigurerAdapter.

Specific code implementation:

@Component
public class MyWebConfiguration extends WebMvcConfigurationSupport{
  @Resource
  private RequestFilter requestFilter;
  @Override
  public void addInterceptors(InterceptorRegistry registry) {
    // 跨域拦截器
    registry.addInterceptor(requestFilter).addPathPatterns("/**");
  }
}

The above is the detailed content of How Springboot solves the cross-domain request problem of ajax custom headers. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:yisu.com. If there is any infringement, please contact admin@php.cn delete