First of all, thank you for a few articles, learn a lot 😀

  • Remember a preflight request for cross-domain POST request data
  • Resolved a preflight request failure in a cross-domain request
  • Why does AXIos request Options first before asking for post and resolution

In the above article, the big guys have summed up a lot and very detailed, the following is some personal summary

First, background

The locally started front-end Vue project uses AXIOS to send a POST request to get a display list, and the back-end project has been configured as follows for the cross-domain requests that might be generated

response.setHeader("Access-Control-Allow-Origin",request.getHeader("Origin"));
response.setHeader("Access-Control-Allow-Methods"."*");
response.setHeader("Access-Control-Allow-Credentials"."true");
response.setHeader("Access-Control-Allow-Headers"."Authorization,Origin, X-Requested-With, Content-Type, Accept,Access-Token");
Copy the code

The front-end request is

axios.post(myUrl, {
    token: myToken,
}).then( res= > {
    // do sth success
}).catch( err= > {
    // do sth error
})
Copy the code

The browser console then displays as

2. Preliminary analysis

Redirect is not allowed for a preflight request. Redirect is not allowed for a preflight request. Redirect is not allowed for a preflight request. Preflight Request = preflight request = preflight request = preflight request = preflight request = preflight request

  1. When AXIos uses post requests, it sends an option request first by default
  2. Axios uses post requests when the default isContent-Typeisapplication/json
  3. useFormDataFormat parameters as parameters in a POST request do not cause cross-domain problems andpreflight requestAn error

2.1 Request Types

  • A simple request
  • Non-simple request

2.1.1 Simple Request

The following two conditions are met

  1. The request method is one of three:
  • HEAD
  • GET
  • POST
  1. Content-type: (This is a simple requirement only if the POST method’s content-type value is equal to one of the following)
  • text/plain
  • multipart/form-data
  • application/x-www-form-urlencoded

For simple requests, the browser issues CORS requests directly.

  • Access-control-allow-origin: This field is required. Its value is either the value of the Origin field at the time of the request, or an *, indicating acceptance of requests for any domain name.
  • 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 are not included in CORS requests. If set to true, the server explicitly approves that cookies can be included in the request and sent to the server. This value can only be set to true if the server does not want the browser to send cookies.
  • 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.

2.1.2 Non-simple Requests

  1. The request method is not GET/HEAD/POST
  2. The content-type of a POST request is not Application/X-www-form-urlencoded, multipart/form-data, or Text /plain
  3. The request sets a custom header field
  • Non-simple requests are requests that have special requirements on the server, such as the request method being PUT or DELETE, or the content-Type field being of Type Application/JSON
  • CORS requests that are not simple requests are preceded by an HTTP query request, called a “preflight” request.
  • The request method for the “precheck” request is OPTIONS, indicating that the request is being queried. In the header information, the key field is Origin, indicating which source the request came from
  • 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
  • In addition to the Origin field, the precheck request header contains two special fields:
    • Access-control-request-method: This field is required to list which HTTP methods are used by the browser for CORS requests
    • Access-control-request-headers: This field is a comma-separated string that specifies the additional header field that a browser CORS Request will send

2.1.3 Why is the pre-check request sent

Preflight Request is a precheck request made by the browser to ensure that the server is not allowed to make HTTP requests that have adverse effects on server data. If the request is allowed, the browser will send a real request. If not, the browser will reject the real request.

Third, problem backtracking

  1. Post request using Axios, andContent-TypeThe default isapplication/jsonformat
  2. Since it is not a simple request, the browser will first send an option request, although the backend has been set to resolve cross-domain, but it appearspreflight requestAn error

Fourth, try to solve

Methods 4.1 a

When sending AXIos to send a POST request, configure the header property + the AXIos data field

Note: Application /x-www-form-urlencoded, the browser will not error the preflight request, but the backend will probably not get the data, because even though the format is Application/X-www-form-urlencoded, But the argument sent is still a JSON string

If you want to solve this problem has thought of before his hair a article, -_ – | |, portal: using axios climb pit diaries 】 【 submit formdata post

🚀 advanced version: you can add QS conversion

// Only the preflight request error is resolved
axios({
    method: 'post'.url: myUrl,
    data: {
        token: myToken,
    },
    headers: {
        'Content-Type': 'application/x-www-form-urlencoded',}})Copy the code

4.2 method 2

Use the FormData parameter format + axios data field

let formData = new FormData();
formData.append('token', myToken);
axios({
    method: 'post'.url: myUrl,
    data: formData,
})
Copy the code

When sending a request using formData, AXIOS does not send an option request up front, just a POST request

4.3 method 3

Use axios’ params field directly

axios({
    method: 'post'.url: myUrl,
    params: {
        token: myToken,
    },
})
Copy the code

When a request is sent using the Params field, AXIos does not send an option request up front, just a POST request

Add: If AXIos makes a POST request and uses the data field directly, the browser will report a preflight Request error and the browser will send an option request first

Summary of personal POST requests to Axios

In the end, there are several solutions. In my opinion, they all use key/value format parameters as the ultimate goal

  1. When using method three, although not setContent-Typeforapplication/x-www-form-urlencoded, but the parameter format iskey/value
  2. When using method two, it’s standard formDatakey/valueformat
  3. When using the normal version of method 1, although the browser does not reportpreflight requestWrong, but seeing the parameters is notkey/valueformat
  4. When using the advanced version of method one, the argument is alreadykey/valueFormat, but there are subtle differences between discovery and method two

Six, from the personal summary of the extension of the rightapplication/x-www-form-urlencodedandmultipart/form-dataconfusion

Reference: www.cnblogs.com/dd86/p/1119…

The different encoding methods of the form

  • The encType attribute of form is coded, and there are two commonly used methods: Application/X-www-form-urlencoded and multipart/form-data. The default is Application/X-www-form-urlencoded.

  • When the format is get, the browser uses the application/x-www-form-urlencode encoding to convert the form data to a string, such as (name=zhangsan&age=128), and then appends this character to the URL, using? The connection forms a new URL and loads it

  • The browser wraps the FORM data in an HTTP body when the data is delivered via POST and sends it to the server. If you don’t have controls for type=file, use the default Application/X-www-form-urlencoded. But if type=file, use multipart/form-data. The browser splits the entire form by control and adds content-disposition (form-data or file),Content-Type(default text/plain),name(control name) to each part. And add the boundary.