The front and back end separation is the general trend, the cross-domain problem is a platitudes, just use the title to Google or Baidu, you can find a large number of solutions, so why write it again, don’t hurry to look down.

Background:

Same Origin Policy. It is an important security metric for client-side scripts, especially JavaScript, to prevent a document or script from being loaded from multiple “origin” sources. It considers trusted content loaded from any site to be unsafe.

When half-trusted scripts run in the sandbox by browsers, they should only be allowed to access resources from the same site, not potentially malicious resources from other sites.

Note: Have the same Origin, that is, have the same protocol, host address and port. If one of the three items of data is different, the resource will be considered to have come from a different Origin and therefore will not be allowed access.

CORS was developed to solve the SOP problem. Of course, CORS is not the only solution, but there are no other solutions here.


CORS introduction:

CORS is a W3C standard, which stands for “Cross-origin Resource Sharing”. It allows browsers to make XMLHttpRequest requests to servers across sources (protocol + domain + port), overcoming the limitation that AJAX can only be used in the same source. CORS requires both browser and server support. Its communication process, is automatically completed by the browser, does not require user participation.

For developers, CORS communication is no different from same-origin AJAX/Fetch communication, with the code exactly the same. As soon as the browser discovers that the request is cross-sourced, it automatically adds some additional headers, and sometimes an additional request, but the user doesn’t feel it. Therefore, the key to CORS communication is the server. As long as the server implements the CORS interface, cross-source communication is possible.

Browsers classify CORS requests into two categories: Simple request and not-so-simple Request.

The browser makes a simple CORS request and simply adds an Origin field to the header information.

When the browser makes a CORS request, it adds an OPTIONS query request, called a “preflight” request, before formal communication. The browser asks the server if the domain name of the current web page is on the server’s license list, and what HTTP verb and header fields can be used. The browser issues a formal XMLHttpRequest request only if it receives a positive response; otherwise, an error is reported.

A simple request is a HEAD, GET, or POST request. The HTTP header does not exceed the following fields: Accept, Accept-language, Content-language, last-event-ID, or Content-Type note: Content-type: Application/X-www-form-urlencoded, multipart/form-data, text/plain

Otherwise, it is a non-simple request.

In fact, the implementation of CORS is very simple, is to add some response headers on the server side, and this is insensitive to the front-end, very convenient.

Detailed response header:

  • Access-control-allow-origin Specifies the Origin field. The value is either the exact value of the Origin field at the time of the request, or an *, indicating that requests for any domain name are accepted.
  • Access-control-allow-methods This field is mandatory. Its value is a concrete string or * separated by commas, indicating all methods supported by the server for cross-domain requests. Notice that all supported methods are returned, not just the one requested by the browser. This is to avoid multiple “pre-check” requests.
  • Access-control-expose-headers This field is optional. In CORS requests, the getResponseHeader() method of the XMLHttpRequest object takes only six basic fields: Cache-control, Content-language, Content-Type, Expires, Last-Modified, Pragma. If you want to get other fields, you must specify access-Control-expose-headers.
  • Access-control-allow-credentials This field is optional. Its value is a Boolean value indicating whether cookies are allowed to be sent. By default, cookies do not occur, that is: false. This value can only be set to true for requests that have special requirements on the server, such as the request method PUT or DELETE, or the content-Type field Type application/ JSON. If the server does not want the browser to send cookies, delete this field.
  • Access-control-max-age Specifies the validity period of the precheck request, in seconds. There is no need to issue another precheck request during the validity period.

By the way, if you find that there are two requests issued each time, one OPTIONS and one normal request, then you need to configure access-Control-max-age to avoid issuing precheck requests every time.

Solutions:

The first method:
import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class CorsConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOrigins("*") .allowedMethods("GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS") .allowCredentials(true) .maxAge(3600) .allowedHeaders("*"); }}Copy the code

This approach is globally configured, and is mostly the workaround on the web, but many are based on older Spring versions such asWebMvcConfigurerAdapterIn spring5.0 it has been marked Deprecated, click open source to see:

/** * An implementation of {@link WebMvcConfigurer} with empty methods allowing * subclasses to override only the Methods they're interested in. * * @author Rossen Stoyanchev * @since 3.1 * @deprecated as of 5.0 {@link WebMvcConfigurer} has default methods (made * possible by a Java 8 baseline) and can be implemented directly without the  * need for this adapter */ @Deprecated public abstract class WebMvcConfigurerAdapter implements WebMvcConfigurer {}Copy the code

Spring’s authors will always comment on outdated classes or methods like this and tell you which one to use. This is good coding practice, thumbs up!

Spring5 supports as little as jdk1.8, so the comments make it clear that you can implement the WebMvcConfigurer interface directly without using the adapter, because jdk1.8 supports default-method.

I will not introduce the basics of Spring Boot. This tutorial is too complete.

Github.com/javastacks/…


The second method:
import org.springframework.context.annotation.Configuration; import javax.servlet.*; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @WebFilter(filterName = "CorsFilter ") @Configuration 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-Credentials", "true"); response.setHeader("Access-Control-Allow-Methods", "POST, GET, PATCH, DELETE, PUT"); response.setHeader("Access-Control-Max-Age", "3600"); response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); chain.doFilter(req, res); }}Copy the code

This approach, based on filters, is simple and clear, is to write these response headers in response, a lot of articles are the first way and the second way call you configure, actually this is not necessary, just one way.

Here is also a joke, we do not understand the spirit. In addition, pay attention to the public account Java technology stack, in the background reply: interview, you can get my organized Spring Boot interview questions and answers.


The third way:
public class GoodsController {
@CrossOrigin(origins = "http://localhost:4000")
@GetMapping("goods-url")
public Response queryGoodsWithGoodsUrl(@RequestParam String goodsUrl) throws Exception {}
}  
Copy the code

That’s right ** @crossorigin ** annotation, click on annotation

@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CrossOrigin {

}
Copy the code

As you can see from the @target meta-annotation, annotations can be placed on methods, classes, etc., similar to RequestMapping, that is, methods under the controller can be controlled as a whole, or individual methods can be controlled.

As you can see, this is the least granular cORS control approach, down to the level of a single request.

Reprinted from: www.telami.cn/2019/spring…