This is the fifth day of my participation in the August More text Challenge. For details, see: August More Text Challenge

Note at the beginning: “cross-domain” should be referred to as “cross-origin”, corresponding to The English cross-origin, but the former is used more frequently. Considering the commonness of language conventions, it can be considered that the words “cross-domain” and “cross-source” can be replaced equivalently, so this paper will use them indiscriminately.

The same-origin policy

To ensure the security of user information, browsers apply a series of security policies, one of which is the same-Origin policy (SOP).

By homology, we mean the same of:

  • The agreement is the same
  • Domain name is the same
  • Same port number

The same origin policy is used to constrain cross-domain interactions, which generally fall into three categories:

  • Cross-domain writecross-origin writes: Such as links<a>, redirection, and form submission.
  • Cross-domain resource embeddingcross-origin embedding: Such as using<script>Embed script, use<img>Tags show pictures, use<link rel="stylesheet">The introduction ofCSSStyle and so on.
  • Cross-domain readcross-origin reads: for instance,XMLHttpRequestRequest, readDOMObject, readJSObject and so on.

Not all cross-domain interactions are prohibited:

  • Generally, cross-domain writes are allowed, but only a few are allowedHTTPRequest needs to addpreflight.
  • Cross-domain resource embedding is generally allowed.
  • Generally, cross-domain reads are prohibited.

Cross-domain problem

Cross-domain problem refers to the problem caused by the restriction of some cross-domain interactions under the same-origin policy. For example, when the front end sends a cross-domain AJAX request during interface debugging, if the cross-domain problem is not handled, an error will be reported in the browser console:

Access to XMLHttpRequest at 'aaa' from origin 'bbb' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Copy the code

In general, the same origin policy restricts the following three cross-domain behaviors, all of which are cross-domain reads:

  • Cookie,LocalStorageIndexedDBUnable to read.
  • DOMNot available. Disables pages that are not of the same originDOMFor example, different domain name<iframe>Cannot access each other.
  • AJAXRequest (XMLHttpRequest) Cannot send.

CORS Cross-source resource sharing

Introduction of CORS

CORS is short for Cross-Origin Resource Sharing, which is often referred to as cross-domain resource sharing. It is a mechanism based on HTTP header fields that solves cross-domain problems from the server side (back end).

Simple request and precheck request

But browsers are divided into two types of requests, simple requests and preflighted requests, and the processing of these two types of requests is different.

A simple request is a request that satisfies all of the following conditions:

  • The request method isGET,POST,HEADOne of them
  • Excluding the header field automatically set by the user agent, the header field contains only the following:
    • Accept
    • Accept-Language
    • Content-Language
    • Content-TypeTechnology:text/plain,multipart/form-dataapplication/x-www-form-urlencoded
    • DPR
    • Downlink
    • Save-Data
    • Viewport-Width
    • Width
  • Any in the requestXMLHttpRequestUploadObject is not registered with any event listeners.
  • Not used in the requestReadableStreamObject.

Any request that does not meet these conditions is a precheck request. The main difference between a simple request and a precheck request is that there is no precheck step in a simple request, so a simple request can also be understood as a request that does not trigger a CORS precheck request.

Simple request workflow:

  • The browser determines that a request is a simple request and automatically adds it in the header fieldOriginField, and then send the request to the server.
  • Server viewOriginIf yes, return withAccess-Control-Allow-OriginThe response to the header field. If not, the general response is returned, which does notAccess-Control-Allow-Origin.Access-Control-Allow-OriginThe value of is usually*Or in the requestOriginSpecifies the domain.
  • The browser views the response, if it existsAccess-Control-Allow-OriginHeader field, the response is processed normally. If there is no field, the request violates the same origin policy and an exception is thrown.

Workflow of precheck request:

  • Before formally requesting the server, the browser will make a precheck request as followsOPTIONS. It needs to includeOriginHeader field to specify the source from which the request came, among other thingsAccess-Control-Request-MethodAccess-Control-Request-HeadersThe two header fields.
  • The server receives the request and returns withAccess-Control-Allow-OriginThe response for the header field needs to be specified as*Or in the requestOriginField.
  • If the server does not allow the cross-domain request, the response is returned with noAccess-Control-Allow-Origin, the browser will throw an exception.
  • After the precheck request is successful, the actual request is sent. The workflow is similar to that of a simple request. The request sent by the browser needs to be carriedOriginHeader field, which the response returned by the server needs to carryAccess-Control-Allow-OriginField.
  • For precheck requests, there is no need to start each timeOPTIONRequest, within a certain period of time, can not be sent repeatedly. Responding on the serverOPTIONPrecheck request, can passAccess-Control-Max-AgeTo set the duration of the response. Note that the browser itself maintains a maximum validity period, and if the value of the header field exceeds the maximum validity period, it will not take effect.

CORS Request header field

  • Origin: Specifies the source of the precheck request or the actual request.OriginParameter is the source siteURI. It does not contain any path information, just the server name. In all access control requests (Access control request),OriginThe header field is always sent.
  • Access-Control-Request-Method: Reserved for precheck requests that will be used for actual requestsHTTPMethod tells the server.
  • Access-Control-Request-Headers: Precheck request, the actual request to carry the header field to tell the server. Multiple fields are separated by commas.

CORS Response header field

  • Access-Control-Allow-Origin: Specifies the permission to access the resourceURI. For requests that do not need to carry credentials, the server can specify the value of this field as a wildcard, indicating that requests from all domains are allowed. If the server specifies a specific domain name instead of*, then in the response headervaryThe value of the field must containOrigin. This tells the client that the server is returning different content for different source sites.
  • Access-Control-Expose-Headers: In cross-source access,XMLHttpRequestThe object’sgetResponseHeader()Method can only get the most basic response headers,Cache-Control,Content-Language,Content-Type,Expires,Last-Modified,PragmaIf you want to access other headers, the server needs to set this response header. Such asAccess-Control-Expose-Headers: X-My-Custom-Header, X-Another-Custom-Header.
  • Access-Control-Max-Age: sets how long the results of precheck requests can be cached, in seconds.
  • Access-Control-Allow-Credentials: in order totrueIs displayed, the server allows the browser to send packetscookie. The value can only betrueIf the server does not need the browser to sendcookie, do not write the field. If the response carries this field,Access-Control-Allow-OriginCan’t for*Must be explicitly specified as the domain name of the sender of the request.
  • Access-Control-Allow-Methods: Is used to respond to precheck requests and specify what is allowed for the actual requestHTTPMethods.
  • Access-Control-Allow-Headers: used in response to a precheck request, indicating the header field allowed in the actual request.

Spring Boot solves cross-domain problems

In Spring Boot, there are a variety of solutions to solve cross-domain problems. The four solutions mentioned here fall into two categories based on their scope:

  • Local cross-domain
  • Across the global scope

Local cross-domain

  1. use@CrossOriginannotations
  • The application inControllerClass allows all interfaces below the class to receive cross-domain requests
@RestController
@CrossOrigin
public class HelloController {
    @GetMapping("/hello")
    public String hello(a) {
	    return "hello"; }}Copy the code
  • The application inControllerClass to allow the method to receive cross-domain requests
@RestController
public class HelloController {
    @GetMapping("/hello")
	@CrossOrigin
    public String hello(a) {
	    return "hello"; }}Copy the code
  1. useHttpServletResponse, manually add fields to the response headerAccess-Controll-Allow-Origin
@RestController
public class HelloController {
    @GetMapping("/hello")
    public String hello(HttpServletResponse response) {
	    response.addHeader("Access-Control-Allow-Origin"."http://localhost:8080");
	    return "hello"; }}Copy the code

Across the global scope

  1. defineCorsConfig.javaConfiguration class, implementationWebMvcConfigurerInterface, overrideaddCorsMappingsMethods.
@Configuration
public class CorsConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/ * *")
        .allowedOrigins("http://localhost:3000")
		.allowedHeaders("*")
        .allowedMethods("GET"."POST"."PUT"."DELETE")
		.allowCredentials(true)
		.maxAge(86400); }}Copy the code
  1. Use a filter
@Configuration
public class WebConfig  {
    @Bean
    public CorsFilter corsFilter(a) {
        CorsConfiguration config = new CorsConfiguration();

        config.addAllowedOrigin("https://localhost:3000");
        config.setAllowCredentials(true);
        config.addAllowedMethod(CorsConfiguration.ALL);
        config.addAllowedHeader(CorsConfiguration.ALL);

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/ * *", config);

        return newCorsFilter(source); }}Copy the code

The resources

  • Description of cross-domain resource sharing CORS
  • MDN-CORS