Recently, the company arranged a public account webpage project. It happened to be a period of time that we did not use Vue to build the project. I think we should start from Vue, and now the scaffolding has reached 3.0. And then we hit a lot of holes.
Vue built the request interface debugging, naturally using the official recommended Axios, then encountered a small problem, normal Post request, inexplicably changed into OPTIONS request.
HTTP request methods
The most common HTTP requests for development are POST and GET. But HTTP provides more than one way to request.
- GET: Usually used to request the server to send certain resources
- – This request method can be used to determine the size of a large file before downloading it to save bandwidth resources
- OPTIONS: Used to obtain the communication OPTIONS supported by the destination resource
- POST: sends data to the server
- PUT: Used to add a resource or replace the representation of the target resource with the payload in the request
- DELETE: deletes a specified resource
- PATCH: used to partially modify resources
- CONNECT: reserved in HTTP/1.1 for proxy servers that can pipe connections
- TRACE: displays the requests received by the server for testing or diagnosis
The specific application of these methods will not be discussed here
An error condition
In the code, it is a Post request, but in the Google control panel, it shows OPTIONS. Why?
The root cause
Initially, I thought it might be a cross-domain problem, and then I added a response header to the background, but the problem was not solved. Later, according to the English prompt, I asked for violation of CORS protocol and inquired about CORS on MDN.
After looking through the MDN introduction to CORS (CORS Introduction link), you can see the following paragraph in the function overview:
The CROSS-Domain Resource Sharing Standard (CORS) has added a new set of HTTP header fields that allow servers to declare which sources have access to which resources through the browser. In addition, the specification requires that HTTP request methods (especially HTTP requests other than GET, or POST requests paired with certain MIME types) that may have adverse effects on server data, The browser must first issue a preflight request using the OPTIONS method to know whether the server will allow the cross-domain request. The actual HTTP request is made only after the server confirms that it is allowed. In the return of the precheck request, the server side can also inform the client whether it needs to carry identity credentials (including Cookies and HTTP authentication related data). CORS request failures generate errors, but for security reasons, there is no way to know exactly what went wrong at the JavaScript code level. You can only look at your browser’s console to see exactly what went wrong.
For cross-domain requests, except GET requests or POST requests with MIME types, a pre-request is sent with OPTIONS to check whether the server allows the cross-domain request. POST requests that do not conform to the specification will be blocked out, which is why the above error occurs. Only OPTIONS requests are sent, but important posts are not sent.
Now that you know what the problem is, you need to make the requests you send comply with the CORS protocol. Request header field content-type is not allowed by access-Control-allow-headers in preflight response. The content-Type of Access-Control-allow-headers does not meet the requirements, so CORS detection is triggered.
The solution
Now that you know that the request was changed because CORS detection was triggered, success can be guaranteed as long as you comply with CORS specifications and avoid detection. After consulting the data, the following contents can be found to avoid detection. MDN reads as follows (simple request) :
Some requests do not trigger CORS precheck requests. This article refers to such a request as a “simple request,” noting that the term is not part of the Fetch (where CORS is defined) specification. A request is considered a “simple request” if all of the following conditions are met:
- Use one of the following methods: GET HEAD POST
- The Fetch specification defines a set of header fields that are CORS safe. No header fields other than this set may be set artificially. The set is:
- Accept
- Accept-Language
- Content-Language
- Content-type (Additional restrictions need to be noted)
- DPR
- Downlink
- Save-Data
- Viewport-Width
- Width
- The value of the content-type is limited to one of the following:
- text/plain
- multipart/form-data
- application/x-www-form-urlencoded
Please note that all conditions are required. Combined with the control panel message and error message, the message is sent in a format that does not belong to either of the Content-Types. Therefore, CORS detection is triggered, causing the POST request to fail. All you need to do is make the parameter of one of the formats specified in the content-Type above.
validation
What I passed to the background was an Object with unprocessed parameters, which did not belong to the above three types. Therefore, the solution was to process the passed parameters to meet the requirements.
-
String conversion of arguments
As a rule of thumb, when json.stringify () is applied to the parameters, you can see that the request has been completed, but the parameters passed to the background are not what the background wanted. So doing so may require some backstage cooperation. PS: The last company did this with metrics, so this is also a verification guess, which is actually useful.
You can see that the arguments are in the form of strings.
-
In AXIOS, you can use the URLSearchParams API
var data = new URLSearchParams(); data.append('id'.'1'); data.append('name'.'minmin'); data.append('age'.'23') axios.post('url, data).then( res => { ... })Copy the code
However, there is a bit of inconvenience, if the parameters are too many, this way is laborious, so it is better to use plug-ins to solve
-
Use plug-ins to solve, reference QS in the project
CNPM install --save qs install --save QSCopy the code
// Encapsulate the request method with qs.stringify(data) for all parametersfunction httpRequest(url, method, data) { letrdata = { ... publicData, ... data } rdata = qs.stringify(rdata)if (method === "post") { return post(url, rdata) } else { return get(url, rdata) } } Copy the code
conclusion
Personally, I recommend using a plugin in the project. It takes time and effort to pass the append parameter each time. Of course, if the company uses the first method to pass the parameter to the background, it is ok to use the plugin.