If you’ve ever tried to request an external API through a framework or a browser’s FETCH or XHR while developing a website, you’ve probably encountered cross-domain requests and that egregious CORS error message; Today we will discuss the causes and solutions of cross-domain problems.

Cross-domain request

If you haven’t, try typing the following code on your browser’s console page:

const xhr = new XMLHttpRequest() xhr.onreadystatechange = () => { if (xhr.readyState === 4) { console.log(xhr.status === 200? xhr.responseText : 'error') } } xhr.open('GET', 'https://google.com') xhr.send()Copy the code

This code makes a request to Google by calling the browser’s XMLHttpRequest, and the result looks something like this:

This is the cross-domain request problem. When a request is sent via JavaScript to a different source, the response to the request is intercepted by the browser and not handed to JavaScript for processing. By “different source” we mean that the source of the target resource is different from the domain, protocol, or port of the current web page, if any one of them is different. Here are some examples:

Assume the current user is at: https://example.com: [✅] with domain https://example.com/test - > [❌] https://m.example.com - > different domain https://example.com:3000 - > [❌] port [❌] http://example.com -> Different communication protocolsCopy the code

Now that you understand what cross-domain is, why do browsers block cross-domain request resources?

In fact, this is to consider the user’s information security.

Assuming that Xiao Hei is a malicious developer, his website will try to hit baidu, Weibo and other target websites through XHR. If the user already has the login status of the target website, the black man can pry into his privacy and obtain data that should not be accessed. Think about it. If the target sites were Email, banking, e-commerce, and no browser to limit the protection of cross-domain requests, malicious developers could do whatever they wanted.

Note: Cross-domain requests are intercepted by browsers, but only in Response, not Request.

The solution

There are many solutions to cross-domain request, such as JSONP, which is to use HTML tags such as IMG and Script without cross-domain restrictions, and then specify callback functions to interface the content of the response back to JavaScript. Or through iframe, bypassing cross-domain protection to obtain target resources. The following are just two common and relatively formal solutions.

CORS

The most standard and correct solution is through the W3C specification of cross-Origin Resource Sharing (CORS), which enables browsers to retrieve resources from different sources through server Settings in the HTTP header.

In CORS specification, the operation mode of cross-domain access control is clearly defined.

Access-control-allow-origin = access-Control-request-method = access-Control-request-headers = access-Control-allow-origin = access-Control-request-method = access-Control-request-headers To limit the sources that the server can accept, how requests are made, what can be carried, etc.

When the browser sends a resource request, it sends the request directly if it is simple. But are not but a formal request is sent but a Preflighted request is done by knocking on the door to confirm that it is ok to get past the limitations of the server.

In addition to the above contents, CORS also has information about the transmission mode of Cookies and how to allow cross-domain writing of Cookies.

Proxy server

Since the CORS header is set on the server side, if the server is your own, you can easily adjust the server Settings so that the front-end can get the necessary resources. But if you’re requesting an external API, you can’t ask someone to change the header every time you get a CORS error.

The simple and violent way is to get resources for us through proxy servers; Since the limitation of cross-domain protection is the specification of the browser, there is no limitation as long as the request is not sent through the browser.

The common approach is to do a simple reverse proxy through Nginx; For example, in your own development environment, the front-end and back-end architecture is separated, and the front-end and back-end services are started on port 3000 and port 5000 respectively, you can use the following configuration:

server{ listen 3000; server_name localhost; location ^~ /api { proxy_pass http://localhost:5000; }}Copy the code

To send an API request, you can directly request localhost:3000/ API /… The request is intercepted by Nginx and forwarded to localhost:5000, where the backend resides, thus simply bypassing the cross-domain protection.

conclusion

Cross-domain is a common requirement on the front end, and CORS error messages are where we can easily get stuck; In fact, as long as you know the HTTP header Settings in the CORS specification and make corresponding adjustments on the server side, you can successfully complete the cross-domain request.

Welcome to pay attention to my public number: front-end pioneer