After the backend allows cross-domain, the front-end access still has cross-domain problems

Problem Description:

When uploading files, since there are multiple back-end servers, before uploading the address, an interface on the back-end will be called to obtain the actual upload address. However, the upload address obtained each time is different, and it is impractical to use ngnix to solve cross-domain problems, so the backend enables cors and cross-domain resource sharing. But it still gives an error later.

Error:

Access to XMLHttpRequest at ‘http://192.168.1.XXX:9191/mpn/file/4715ff4efb35423c87972aa2c959bdf2‘from origin’http://192.168.3.XXX:8089‘ has been blocked by CORS policy: Request header field x-cs-content-length is not allowed by Access-Control-Allow-Headers in preflight response.

Capture packets:

Capture the packet for the request to upload the file, check the request header and find

Access-Control-Allow-Credentials: true

Access-Control-Allow-Headers: Origin, Content-Type, AccessToken, X-CSRF-Token, Authorization, Token

Access-Control-Allow-Methods: POST, GET, PUT, DELETE, OPTIONS

Access-Control-Allow-Origin: *

Access-Control-Expose-Headers: Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Content-Type

Content-Type: application/json; charset=utf-8

Date: Thu, 07 Jul 2022 05:54:20 GMT

Content-Length: 158

Connection: clos

The red font indicates that the backend allows cross-domain request headers

And my custom request header is:

headers: {

‘Content-Type’: ‘application/octet-stream’, ‘x-cs-content-method’: me,

‘x-cs-content-length’: allLength, ‘x-cs-range’: bytes, ‘ETag’: ETag,

}

The reason for the problem:

The front end defines request headers that the back end is not allowed to cross-domain

Solution:

Backend customization adds request headers that allow cross-domain, such as python:

# If the backend is python

from corsheaders.defaults import default_headers

CORS_ALLOW_HEADERS = default_headers + (
    'Allow cross-domain request headers' 
)

Extension:

Reference blog: Do you know why options requests are sent across domains? – Nuggets

Every time a file is uploaded, the browser sends two requests

The first request shows the type as preflight and the launcher shows as preflight

And looking at the header, the method of this request is OPTIONS 

  1. Cause:

In the CORS mechanism, the client (browser) divides requests into two types , simple requests and complex requests

For simple requests, the following requirements need to be met:

  • The request methods are: GET , POST , HEAD

Where Content-Type is limited to:

text/plain、multipart/form-data、application/x-www-form-urlencoded

And my current request method is  Put, and I have customized the request header, so of course it is a complex method and needs to be pre-checked

  1. Function:

Why pre-check?

  1. Get the HTTP request methods supported by the server;
  2. Used to check server performance. For example, when AJAX performs cross-domain request pre-check, it is necessary to send an HTTP OPTIONS request header to the resource of another domain name to determine whether the actually sent request is safe.

3. Process:

Reference document: Detailed explanation of http CORS options request (preflight request) – Programmer Sought

a. For simple requests:

The browser directly sends the CORS request this time, and will carry an additional request header parameter: Origin

​​​​​​Origin : http://192.168.3.229:8089

This parameter shows which source (protocol, domain name, port) the request came from. Based on this value, the server decides whether to agree to the request. 

If Originthe specified source is not permitted, the server will return a normal HTTP response. The browser finds that the header information of this response does not contain a Access-Control-Allow-Originfield, so it knows that an error has occurred, and thus throws an error, which is caught by XMLHttpRequestthe onerrorcallback function. This error cannot be identified by the status code, because the status code of the HTTP response may be 200.

b. For complex requests:

The browser will first make a preflight request, the request method is OPTIONS, and it carries two important request header information:

Access-Control-Request-Method

This field is required. It is used to list which HTTP methods will be used in the browser’s CORS request. I use the Put method.

Access-Control-Request-Headers

This field is a comma-separated string that specifies additional header fields that browser CORS requests will send

The browser judges through the information returned by the preflight request, whether the information (request header, method) carried by the request to be sent is accepted by the server, and whether the domain name of the current webpage is in the server’s allow list, only if it gets a positive reply, The browser will issue a formal XMLHttpRequestrequest, otherwise it will report an error.

The return information of the preflight request:

Access-Control-Allow-Origin:*

With this field, it means that cross-domain is allowed

If this field is not included, it proves that the server does not accept the request and the request fails

PS: If it still fails, check whether the methods allowed by the backend include the methods used by the request

Leave a Comment

Your email address will not be published. Required fields are marked *