Cross domain problem principle and solution

1. Before understanding cross-domain, let me talk about what is the same-origin policy?

If the protocols, domain names, and ports of the two pages are exactly the same, it means that the two pages have the same origin. If one of them is different, it is a different source.

The Same Origin Policy (English full name Same origin policy) is a security feature provided by browsers.

The same-origin policy restricts how documents or scripts loaded from the same origin can interact with resources from another origin. This is an important security mechanism for quarantining potentially malicious files.

To put it bluntly, the browser stipulates that the JavaScript of website A is not allowed to interact with non-same-origin website C, for example:
①Unable to read Cookie, LocalStorage and IndexedDB of non-same-origin web pages
② Unable to access the DOM of non-same-origin web pages
③Unable to send Ajax requests to non-same-origin addresses (this sentence is the key: only when sending ajax requests will there be cross-domain problems. ifream and static resources accessing other pages will not have cross-domain problems.)


Both localhost and 127.0.0.1 are different sources. (Reason: localhost can only be converted to 127.0.0.1 when the computer is connected to the Internet. The fundamental reason is that the configuration of the computer allows it to be converted, so they have nothing to do with each other, but people have become accustomed to peering between them in the early stage) .

Example image stolen from Baidu:

2. What is cross-domain and why does cross-domain occur?

The above describes what the same-origin policy is. On the contrary, if the same-origin policy is violated, cross-domain will appear.

After the cross-domain problem occurs, if someone says that this problem can be solved through front-end configuration, it is simply nonsense. (Cross-domain is a back-end problem, and front-end modification alone cannot solve this problem).

The cross-domain error is as follows:

 

A small knowledge point: When cross-domain occurs, it is not that the request is intercepted. In fact, the request can be sent successfully, and the back-end interface can also receive the request and return the data. It's just caused by the browser's same-origin policy. Unresponsive effects appear on the page.

3. After cross-domain occurs, how to solve it?

After the cross-domain is generated, page A needs to access the interface information of program B.

At present, the most commonly used methods that can be found by Baidu are two ways:

JSONP: Appeared early and has good compatibility (compatible with lower versions of IE). It is a temporary solution that front-end programmers are forced to come up with in order to solve cross-domain problems. The disadvantage is that only GET requests are supported, and POST requests are not supported. (Basically no one is using it anymore, and the limitations are too great. But it is also simple to use, the simple code is as follows:)

$.ajax({
	url :'url',
	//If you want to use $.ajax() to initiate a JSONP request, you must specify the datatype as jsonp
	dataType:'jsonp',
	success: function(res) {
		console. log (res)
})

CORS: Appeared late, it is a W3C standard and is a fundamental solution to cross-domain Ajax requests. GET and POST requests are supported. The disadvantage is that it is not compatible with some low-version browsers. (commonly used)

Explain CORS in depth: CORS is actually cross-domain resource sharing, which allows browsers to send XMLHttpRequest requests to cross-origin servers, thus overcoming the limitation that AJAX can only be used on the same origin.

1. Ordinary cross-domain request: only need to set Access-Control-Allow-Origin on the server side
2. Cross-domain requests with cookie s: Both front and back ends need to be set

So the question is, how to set Access-Control-Allow-Origin on the server side?

1. In fact, Spring MVC has already thought of this problem in dealing with this problem. If you want to partially solve the cross-domain problem of an interface, you can add annotations to the interface to solve it.

@CrossOrigin

Disadvantages: The scope of cross-domain solutions is too small. If there are too many interfaces in a system, wouldn't it be exhausting to do so.

    @RequestMapping(value = "/getreferenceauthorization", method = RequestMethod.POST)
    @CrossOrigin
    public String getreferenceauthorization(@RequestBody String params, HttpServletRequest request) {
        try {
            JSONObject jsonObject = JSONObject.parseObject(params);
            String token = jsonObject.getString("token");
            if (ZwdtConstant.SysValidateData.equals(token)) {
                JSONObject obj = (JSONObject) jsonObject.get("params");
               
                // 2. Return data
                JSONObject dataJson = new JSONObject();
                String content = "Please confirm the authorization of your certificate!";
                dataJson.put("noticeContent", content);

                return JsonUtils.zwdtRestReturn("1", "success", dataJson);
            }
            else {
                return JsonUtils.zwdtRestReturn("0", "Authentication failed!", "");
            }
        }
        catch (Exception e) {
            log.error(e.getMessage(), e);
            return JsonUtils.zwdtRestReturn("0", "fail", "");
        }
        finally {
        }
    }

2. Manually set the response header (not recommended, more troublesome than adding annotations)

@RequestMapping("/index")
public String index(HttpServletResponse response) {
 
    response.addHeader("Access-Allow-Control-Origin","*");
    return "index";
}

3. Use a custom filter to achieve cross-domain (it can be used, but as a business development, it is really a bit embarrassing)

@Component
public class MyCorsFilter implements Filter {
 
  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-Methods", "POST, GET, OPTIONS, DELETE");
    response.setHeader("Access-Control-Max-Age", "3600");
    response.setHeader("Access-Control-Allow-Headers", "x-requested-with,content-type");
    chain.doFilter(req, res);
    
  }
  
  public void init(FilterConfig filterConfig) {}
  public void destroy() {}
}

4. Refer to third-party packaged cross-domain components (this is fine, others have already packaged it, we just need to use it.)

cors-filter is a third-party component. Just reference the jar file configuration in the pom file.

		<!-- cross domain request -->
		<dependency>
			<groupId>com.thetransactioncompany</groupId>
			<artifactId>cors-filter</artifactId>
		</dependency>

Then do some basic configuration in web.xml and use it.

<!-- Cross domain filter configuration-->  
  <filter> 
    <filter-name>CORS</filter-name>  
    <filter-class>com.thetransactioncompany.cors.CORSFilter</filter-class>  
    <async-supported>true</async-supported>  
    <init-param> 
      <param-name>cors.allowGenericHttpRequests</param-name>  
      <param-value>true</param-value> 
    </init-param>  
    <init-param> 
      <param-name>cors.allowOrigin</param-name>  
      <param-value>*</param-value> 
    </init-param>  
    <init-param> 
      <param-name>cors.allowSubdomains</param-name>  
      <param-value>false</param-value> 
    </init-param>  
    <init-param> 
      <param-name>cors.supportedMethods</param-name>  
      <param-value>GET, HEAD, POST, OPTIONS</param-value> 
    </init-param>  
    <init-param> 
      <param-name>cors.supportedHeaders</param-name>  
      <param-value>Accept, Origin, X-Requested-With, Content-Type, Last-Modified, Authorization</param-value> 
    </init-param>  
    <init-param> 
      <param-name>cors.exposedHeaders</param-name>  
      <param-value>X-Test-1, X-Test-2</param-value> 
    </init-param>  
    <init-param> 
      <param-name>cors.supportsCredentials</param-name>  
      <param-value>true</param-value> 
    </init-param>  
    <init-param> 
      <param-name>cors.maxAge</param-name>  
      <param-value>3600</param-value> 
    </init-param>  
  </filter>  
  <filter-mapping> 
    <filter-name>CORS</filter-name>  
    <url-pattern>/*</url-pattern> 
  </filter-mapping>  

If no interception is performed at this location, no cross-domain interception will be performed. Whether it is a third-party request or not, there will be no cross-domain problems.

Speaking of which, the backend can basically handle basic cross-domain issues.

But in general, this will not be placed in the filter of web.xml to deal with this problem. If cross-domain is enabled, when connecting with a third-party interface, if the third-party interface changes, you need to change their changed ip in web.xml. Later maintenance is more troublesome, and there will be security problems if it is not turned on.

So: general business development does not need to pay attention to the framework configuration to start to play a role.

Tags: Java Javascript Spring Boot Front-end

Posted by bobohob on Tue, 27 Dec 2022 23:37:35 +0530