From sending a request to returning it requires coordination between the browser and the server. The browser needs to send its request parameters to the server. After verifying the parameters, the server may return data and also tell the browser whether the request is cached or not, such as cookies. This process is more complicated when the request is cross-domain. Let’s take a look at what the cross-domain issues are and how the front and back ends work together.

Ordinary cross-domain

I have a friend, xiao Wang. Front end xiao Wang and back end colleague Ma are going to coordinate a login API. Hypothesis is/login; After getting the login account and password ready, Xiao Wang happily launched the POST submission. Unexpectedly, the request was intercepted by the browser, which helpfully threw an error on the console.



Wang translated, the original was intercepted by CORS strategy. If a server allows a request from a different origin, it should return a response header with a response headerAccess-Control-Allow-OriginThe header. Otherwise, when the browser gets the response and doesn’t find the header in the response header, it will swallow the response instead of handing it to JS for further processing.

Wang told Pony about it, and pony added it to the header he returned

Access-Control-Allow-Origin: *
Copy the code

Now Wang can finally get the results back.

Note that the browser does not intercept the request at the request stage. Instead, the browser sends the request normally. After receiving the response from the server, it checks whether the access-Control-Allow-Origin header is contained in the response header.

Cross-domain of non-simple requests

Later, Wang decided that it was too cumbersome to send the body in form format in POST and preferred to submit the request body in JSON format. Pony thought it was just a matter of a few lines of code, so he agreed. However, after wang changed the message body to JSON, he found that CORS intercepted it again, and threw the following error:

In the error above we see the word preflight. So what’s going on here? After changing the request body, the cross-domain request is no longer a simple request and requires a Preflight request before the request is initiated. So what is a simple request?

  • Request methods includeGET.HEAD.POST
  • Response Headers cannot contain headers other than cORS security headers.
  • The content-type onlytext/plain.multipart/form-data.application/x-www-form-urlencoded

Because of the content-type of the JSON data, this POST request is no longer simple, and for non-simple requests, previously allowing all domain names to cross domain access is prohibited. So you still need to change access-Control-Allow-Origin to the specific requested domain name. In development mode, it might be something like http://localhost:3000.

Xiao ma is re-modifying access-Control-Allow-Origin, and Wang gets the login result again. You can tune into the next API.

Cross-domain with cookies

The login is session-based, that is, after a successful login, the server sets the cookie to the browser through set-cookie. In this way, the cookie will be carried the next time the API of the same origin is accessed.

However, strangely, Wang found that after the login was successful, he called another interface, but the cookie was not brought, so the server could not identify the user information and eventually returned an error (status code 401).

withCredentials

Originally, when the browser initiates a cross-domain request, it does not take the initiative to bring cookies. If a request requires cookies, the developer needs to set an option. Take the FETCH API as an example:

fetch('http://baidu.com:3000', {
    // ...
	credentials: true
})
Copy the code

If you use the XHR API to request, you need to write:

var invocation = new XMLHttpRequest();
var url = 'http://bar.other/resources/credentialed-content/';

function callOtherDomain(){
  if(invocation) {
    invocation.open('GET', url, true);
    invocation.withCredentials = true; / / take a cookieinvocation.onreadystatechange = handler; invocation.send(); }}Copy the code

Wang made another request after setting up the request. But cookie still wasn’t there. Wang had to continue to look at the data in MDN, and found that set-cookie requires a sameSite attribute.

sameSite

SameSite is a property created to protect against CSRF attacks. If you don’t know what a CSRF attack is, you can read this article. Since we need to include cookies in the request, we need to set the sameSite of cookies to None in set-cookie; Since setting sameSite to None also requires Secure, requests need to be based on HTTPS;

Wang appealed to Xiao ma for the last time to change the API, and the server finally recognized who the request came from, and returned the correct result, and the cross-domain trip to the pit was ended.

conclusion

A lot of times, we might just focus on what the request body is and whether the response is returned correctly, ignoring the header part. Headers, like the access-Control-allow -* headers in this article, play an important role in caching, Web security, and proper browser parsing of results.

In order to make the Web more secure, CORS is constantly updated. For example, this proposal stipulates that when accessing the local network from the public network or from the Private network, the cross-domain header, access-Control-allow-private-network, should be set. Hopefully, this article has helped you understand cross-domains. (End of article)

The resources

Developer.mozilla.org/zh-CN/docs/… www.ruanyifeng.com/blog/2019/0… Developer.mozilla.org/zh-CN/docs/… Developer.mozilla.org/en-US/docs/… Developer.mozilla.org/zh-CN/docs/…