Three ways to solve SpringBoot cross domain
- 2021-10-13 07:20:56
- OfStack
1. What is cross-domain
1.1. Why do cross-domain problems occur
Due to the browser's homology policy restriction. Homologous policy (Sameoriginpolicy) is a convention, which is the core and basic security function of browser. If there is no homologous policy, the normal function of browser may be affected. It can be said that Web is built on the basis of homologous policy, and browser is only one implementation of homologous policy. A homology policy prevents javascript scripts in one domain from interacting with content in another domain. Homologous (that is, in the same domain) means that two pages have the same protocol (protocol), host (host) and port number (port)
Simply put, A application can only access the data from the background of A application, and B application can only access the data from the background of B application. If one of the protocols, ports and domain names in URL address when A application obtains data with Ajax corresponds to B application, A application is cross-domain and wants to obtain B application data, which is not allowed
1.2. What is cross-domain
If any one of the protocol, domain name and port requesting url is different from the current page url, it is cross-domain
当前页面URL | 被请求页面URL | 是否跨域 | 原因 |
---|---|---|---|
http://www.test.com/ | http://www.test.com/index.html | 否 | 同源(协议、域名、端口号相同) |
http://www.test.com/ | https://www.test.com/index.html | 跨域 | 协议不同(http/https) |
http://www.test.com/ | http://www.baidu.com/ | 跨域 | 主域名不同(test/baidu) |
http://www.test.com/ | http://blog.test.com/ | 跨域 | 子域名不同(www/blog) |
http://www.test.com:8080/ | http://www.test.com:7001/ | 跨域 | 端口号不同(8080/7001) |
1.3. Non-homologous restriction
For security reasons, the browser restricted 1 requests from accessing non-homologous URL
'1' could not read Cookie, LocalStorage, and IndexedDB for non-homologous web pages
"2" Unable to access DOM of non-homologous web pages
'3' could not send an AJAX request to a non-homologous address
1.4. How to solve cross-domain problems
The server uses pure code logic to solve cross-domain problems. If SpringBoot is used, please see the next chapter
[Tencent Document] JSONP cross-domain solution https://docs.qq.com/doc/DVEVTemdrcVVjSFlE
2. SpringBoot addresses cross-domain issues
①: Returns the new CorsFilter
②: Rewrite WebMvcConfigurer
③: Use the annotation @ CrossOrigin
Note: CorFilter/WebMvConfigurer/@ CrossOrigin needs SpringMVC version 4.2 or above to support, and the first two methods corresponding to springBoot version 1.3 or above belong to global CORS configuration, while the last two belong to local CORS configuration. If local cross-domain is used, it will override the global cross-domain rule,
Therefore, the @ CrossOrigin annotation can be used for fine-grained and higher cross-domain resource control. In fact, no matter which scheme, the ultimate goal is to modify the response header, add the data required by the browser to the response header, and then realize cross-domain
2.1. Configure CorsFilter (Global Cross Domain)
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
@SpringBootConfiguration
public class WebGlobalConfig {
@Bean
public CorsFilter corsFilter() {
// Create CorsConfiguration Add configuration after object
CorsConfiguration config = new CorsConfiguration();
// Set which original domains are released
config.addAllowedOrigin("*");
// Which original request headers are released
config.addAllowedHeader("*");
// What header information is exposed
config.addExposedHeader("*");
// What request methods are released
config.addAllowedMethod("GET"); //get
config.addAllowedMethod("PUT"); //put
config.addAllowedMethod("POST"); //post
config.addAllowedMethod("DELETE"); //delete
//corsConfig.addAllowedMethod("*"); // Release all requests
// Whether to send Cookie
config.setAllowCredentials(true);
//2. Add mapping path
UrlBasedCorsConfigurationSource corsConfigurationSource =
new UrlBasedCorsConfigurationSource();
corsConfigurationSource.registerCorsConfiguration("/**", config);
// Return CorsFilter
return new CorsFilter(corsConfigurationSource);
}
}
If you are using a higher version of SpringBoot 2.4. 4, you need to change it by 1, otherwise, the background will report an error
java.lang.IllegalArgumentException: When allowCredentials is true, allowedOrigins cannot contain the special value "*" since that cannot be set on the "Access-Control-Allow-Origin" response header. To allow credentials to a set of origins, list them explicitly or consider using "allowedOriginPatterns" instead.
at org.springframework.web.cors.CorsConfiguration.validateAllowCredentials(CorsConfiguration.java:453) ~[spring-web-5.3.6.jar:5.3.6]
When allowCredentials is true, alloedOrigins cannot contain the special value "*" because it cannot be set in the "Access-Control-Allow-Origin" response header. To allow credentials to access 1 set of sources, list them explicitly or consider using "AllowedOriginPatterns" instead.
Solution: config. addAllowedOrigin ("*"); Replace with config. addAllowedOriginPattern ("*");
2.2. Override WebMvcConfigurer (Global Cross Domain)
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@SpringBootConfiguration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
// Add mapping path
registry.addMapping("/**")
// Whether to send Cookie
.allowCredentials(true)
// Set which original domains are released SpringBoot2.4.4 Use the lower version .allowedOrigins("*")
.allowedOriginPatterns("*")
// What request methods are released
.allowedMethods(new String[]{"GET", "POST", "PUT", "DELETE"})
//.allowedMethods("*") // Or release all of them
// Which original request headers are released
.allowedHeaders("*")
// What raw request header information is exposed
.exposedHeaders("*");
}
}
2.3. Use the annotation @ CrossOrigin (local cross-domain)
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CrossOrigin {
// This origins And value Yes 1 Like
// A list of allowed source domain names, such as 'www.jd.com' The matching domain name is a cross-domain pre-request Response In the head 'Access-Control-Aloow_origin'
// Field value. Cross-domain access of all domain names is supported by default when the exact value is not set.
@AliasFor("origins")
String[] value() default {};
@AliasFor("value")
String[] origins() default {};
// Under the high version Spring2.4.4 Use originPatterns Instead of value And origins
String[] originPatterns() default {};
// The type of field in the request header allowed in a cross-domain request, This value corresponds to cross-domain pre-request Response In the head 'Access-Control-Allow-Headers' Field value.
// Do not set the exact value. All of them are supported by default header Fields ( Cache-Controller , Content-Language , Content-Type ,
//Expires , Last-Modified , Pragma ) Cross-domain access
String[] allowedHeaders() default {};
// Division allowed in cross-domain request header Cache-Controller , Content-Language , Content-Type , Expires , Last-Modified ,
//Pragma This 6 Field information other than basic fields, corresponding to cross-domain requests Response In the head 'Access-control-Expose-Headers' Field value
String[] exposedHeaders() default {};
// Cross-domain HTTP Supported in the request HTTP Request type ( GET , POST... ), the default is the same as when the exact value is not specified Controller Method in the methods Field retention 1 To.
RequestMethod[] methods() default {};
// This value corresponds to a cross-domain request Response In the head 'Access-Control-Allow-Credentials' Field value.
// Does the browser set the cookie Information is carried to cross-domain servers. It is carried to cross-domain servers by default, but it is necessary to implement cookie
// Sharing also requires the front end to be in AJAX Open on request withCredentials Property.
String allowCredentials() default "";
// This value corresponds to a cross-domain request Response In the head 'Access-Control-Max-Age' Field that represents the maximum cache duration of the preview request response,
// The aim is to reduce browser preview requests / Number of response interactions. Default value 1800s . When this value is set, the browser will no longer initiate a pre-request for the cross-domain request for the time period for which the value is set
long maxAge() default -1;
}
①: Use the @ CrossOrigin annotation on the controller (on the class) to indicate that all methods of the class are allowed to cross domains
@Controller
@RequestMapping("/shop")
@CrossOrigin(originPatterns = "*", methods = {RequestMethod.GET, RequestMethod.POST})
public class ShopController {
@GetMapping("/")
@ResponseBody
public Map<String, Object> findAll() {
// Return data
return DataSchool.getStudents();
}
}
② We can also set smaller granularity and set cross-domain on the method
@Controller
@RequestMapping("/shop")
public class ShopController {
@GetMapping("/")
@ResponseBody
// Smaller solution across domains Set access only to certain addresses
@CrossOrigin(originPatterns = "http://localhost:8080")
public Map<String, Object> findAll() {
// Return data
return DataSchool.getStudents();
}
}
The above is to solve the SpringBoot cross-domain of the details of the three ways, more information about SpringBoot cross-domain please pay attention to the site of other related articles!