Regarding the cross-domain problem of Cors, the front-end has proxy and jsonp as a common way to solve this non-same-origin access denial policy. What is the same origin? That is, two or more types of mutual access with the same domain name and the same port but different interface APIs accessed under the port are called same-origin access. However, if the interfaces are inconsistent or the domain names are inconsistent (here generally refers to inconsistent IPs), then the corresponding ones are non-same-origin access. When accessing, the browser will refuse to send the request and directly reply 404. Sometimes I have also seen that the recovery 202 is sent but rejected by the back-end Mvc processing handler chain. Then configuring MVC is a solution to the Cors problem in the backend.
I have learned the MVC processing link before. From a request sent to the reply data, there are a total of 11 times of processing:
When the request is sent to the server, It is processed by our MVC, and it is our request dispatcher that uniformly allocates the task process. Note that after the request reaches the processor, it goes back to find the processor adapter (requests that meet the verification processing can be allowed, such as the legal api contained in the interface) , and the cross-domain principle), we did not consider cross-domain issues during the development process of our WeChat applet. The reason is that we know that the request processing of the applet is distributed and processed by the WeChat background, that is, when the WeChat background I did cross-domain processing on the front end, probably using dynamic proxy to solve the cross-domain problem of small programs.
Then let’s first take a look at the source code of MVC’s configuration interface WebMvcConfigurer:
public interface WebMvcConfigurer { default void configurePathMatch(PathMatchConfigurer configurer) { } default void configureContentNegotiation(ContentNegotiationConfigurer configurer) { } default void configureAsyncSupport(AsyncSupportConfigurer configurer) { } default void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { } default void addFormatters(FormatterRegistry registry) { } default void addInterceptors(InterceptorRegistry registry) { } default void addResourceHandlers(ResourceHandlerRegistry registry) { } default void addCorsMappings(CorsRegistry registry) { } default void addViewControllers(ViewControllerRegistry registry) { } default void configureViewResolvers(ViewResolverRegistry registry) { } default void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) { } default void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> handlers) { } default void configureMessageConverters(List<HttpMessageConverter<?>> converters) { } default void extendMessageConverters(List<HttpMessageConverter<?>> converters) { } default void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) { } default void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) { } @Nullable default Validator getValidator() { return null; } @Nullable default MessageCodesResolver getMessageCodesResolver() { return null; } }
It has some processor parsers and mapping addition and configuration methods internally, so we need to To solve the Cros cross-domain problem, we need to consider addCorsMappings to configure Cros mapping, so we click in to see the source code of the CorsRegistry that registers Cros:
public class CorsRegistry { private final List<CorsRegistration> registrations = new ArrayList(); public CorsRegistry() { } public CorsRegistration addMapping(String pathPattern) { CorsRegistration registration = new CorsRegistration(pathPattern); this.registrations.add(registration); return registration; } protected Map<String, CorsConfiguration> getCorsConfigurations() { Map<String, CorsConfiguration> configs = CollectionUtils.newLinkedHashMap(this.registrations.size()); Iterator var2 = this.registrations.iterator(); while(var2.hasNext()) { CorsRegistration registration = (CorsRegistration)var2.next(); configs.put(registration.getPathPattern(), registration.getCorsConfiguration()); } return configs; } }
It is not difficult to find from the above code that there is an immutable CorsRegistration array inside. Linked list, as well as the method of adding mapping, the main thing is to look at what configuration items it contains in the element CorsRegistration:
public class CorsRegistration { private final String pathPattern; private CorsConfiguration config; public CorsRegistration(String pathPattern) { this.pathPattern = pathPattern; this.config = (new CorsConfiguration()).applyPermitDefaultValues(); } public CorsRegistration allowedOrigins(String... origins) { this.config.setAllowedOrigins(Arrays.asList(origins)); return this; } public CorsRegistration allowedOriginPatterns(String... patterns) { this.config.setAllowedOriginPatterns(Arrays.asList(patterns)); return this; } public CorsRegistration allowedMethods(String... methods) { this.config.setAllowedMethods(Arrays.asList(methods)); return this; } public CorsRegistration allowedHeaders(String... headers) { this.config.setAllowedHeaders(Arrays.asList(headers)); return this; } public CorsRegistration exposedHeaders(String... headers) { this.config.setExposedHeaders(Arrays.asList(headers)); return this; } public CorsRegistration allowCredentials(boolean allowCredentials) { this.config.setAllowCredentials(allowCredentials); return this; } public CorsRegistration maxAge(long maxAge) { this.config.setMaxAge(maxAge); return this; } public CorsRegistration combine(CorsConfiguration other) { this.config = this.config.combine(other); return this; } protected String getPathPattern() { return this.pathPattern; } protected CorsConfiguration getCorsConfiguration() { return this.config; } }
We can find that it has internal permissions: request header, request path, request method, request source policy method, so we rewrite the addCorsMappings method here to configure a CorsRegistry. Can adding the corresponding path method and request policy release solve the cross-domain problem?
We write a WebMvcConfig configuration class to implement the WebMvcConfigurer interface we just studied, just rewrite addCrosMappings to configure CrosRegistry (or put the @CrossOrigin annotation on the api and Controller control class to solve the problem (the annotation releases requests from all sources by default) )):
/** * 配置前端跨域访问请求 */ @Configuration public class WbMvcConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedHeaders("Content-Type","X-Request-With","Access-Control-Request-Method","Access-Control-Request-Headers","token") .allowedMethods("*") .allowedOriginPatterns("*") /*注意当这个配置为真是我们不能将允许源设置为*而是将源路径设置为*即可*/ .allowCredentials(true); } @Bean public FormContentFilter httpPutFormContentFilter(){ return new FormContentFilter(); } }
We use axios to write a simple request send button:
<input type="button" value="get" class="get"> <script> document.querySelector(".get").onclick = function () { // 跨域一般是是后端解决的事情 axios.get("http://127.0.0.1:8080/all").then( function (response) { console.log(response) } ) } </script>
Then use SpringBoot to write a simple controller api:
@RestController public class testController { @Autowired private ProductServiceImpl productService; @GetMapping("/all") @ResponseBody public List<Product> all() { Page<Product> page = productService.page(1L); List<Product> productList = new LinkedList<>(); productList.add(page.getRecords().iterator().next()); return productList; } }
Here we are browsing Open this html file under port 5050 and click the button to access the interface:
Here you can see that the request to access the data was successful!
The above is the detailed content of How Springboot handles Cors non-original access cross-domain issues by configuring WebMvcConfig. For more information, please follow other related articles on the PHP Chinese website!