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 write
cross-origin writes
: Such as links<a>
, redirection, and form submission. - Cross-domain resource embedding
cross-origin embedding
: Such as using<script>
Embed script, use<img>
Tags show pictures, use<link rel="stylesheet">
The introduction ofCSS
Style and so on. - Cross-domain read
cross-origin reads
: for instance,XMLHttpRequest
Request, readDOM
Object, readJS
Object and so on.
Not all cross-domain interactions are prohibited:
- Generally, cross-domain writes are allowed, but only a few are allowed
HTTP
Request 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
,LocalStorage
和IndexedDB
Unable to read.DOM
Not available. Disables pages that are not of the same originDOM
For example, different domain name<iframe>
Cannot access each other.AJAX
Request (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 is
GET
,POST
,HEAD
One 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-Type
Technology:text/plain
,multipart/form-data
和application/x-www-form-urlencoded
DPR
Downlink
Save-Data
Viewport-Width
Width
- Any in the request
XMLHttpRequestUpload
Object is not registered with any event listeners. - Not used in the request
ReadableStream
Object.
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 field
Origin
Field, and then send the request to the server. - Server view
Origin
If yes, return withAccess-Control-Allow-Origin
The response to the header field. If not, the general response is returned, which does notAccess-Control-Allow-Origin
.Access-Control-Allow-Origin
The value of is usually*
Or in the requestOrigin
Specifies the domain. - The browser views the response, if it exists
Access-Control-Allow-Origin
Header 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 follows
OPTIONS
. It needs to includeOrigin
Header field to specify the source from which the request came, among other thingsAccess-Control-Request-Method
和Access-Control-Request-Headers
The two header fields. - The server receives the request and returns with
Access-Control-Allow-Origin
The response for the header field needs to be specified as*
Or in the requestOrigin
Field. - If the server does not allow the cross-domain request, the response is returned with no
Access-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 carried
Origin
Header field, which the response returned by the server needs to carryAccess-Control-Allow-Origin
Field. - For precheck requests, there is no need to start each time
OPTION
Request, within a certain period of time, can not be sent repeatedly. Responding on the serverOPTION
Precheck request, can passAccess-Control-Max-Age
To 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.Origin
Parameter is the source siteURI
. It does not contain any path information, just the server name. In all access control requests (Access control request
),Origin
The header field is always sent.Access-Control-Request-Method
: Reserved for precheck requests that will be used for actual requestsHTTP
Method 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 headervary
The 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,XMLHttpRequest
The object’sgetResponseHeader()
Method can only get the most basic response headers,Cache-Control
,Content-Language
,Content-Type
,Expires
,Last-Modified
,Pragma
If 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 totrue
Is displayed, the server allows the browser to send packetscookie
. The value can only betrue
If the server does not need the browser to sendcookie
, do not write the field. If the response carries this field,Access-Control-Allow-Origin
Can’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 requestHTTP
Methods.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
- use
@CrossOrigin
annotations
- The application in
Controller
Class 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 in
Controller
Class 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
- use
HttpServletResponse
, 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
- define
CorsConfig.java
Configuration class, implementationWebMvcConfigurer
Interface, overrideaddCorsMappings
Methods.
@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
- 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