What the hell is cross-domain, do you understand?
Cross-domain is a common topic. Recently, no matter when
you are in conjunction with the back-end or micro-front-end, you will encounter
it. Just write an article to summarize it.
Cross-domain is a common topic. Recently, no matter when
you are in conjunction with the back-end or micro-front-end, you will encounter
it. Just write an article to summarize it.
What is cross-domain
"Cross-domain" here refers to resource access
between different sources. As long as the requested url is different from the
following, it belongs to "cross-domain":
•
Protocol: http, https, ...
•
Domain name
• Port
Some people may think that my own website must only access
my own server, and it must be deployed on a domain name.
But sometimes, a webpage may need to connect multiple
back-end services: one for payment, and one for user information. The backend
of each group may have its own domain name. In such scenarios, cross-domain is
very common.
Why is there cross-domain
The "cross-domain" problem we often talk about
is actually talking about the restriction of "cross-domain" access. I
believe everyone is accustomed to the following error reports:
This "cross-domain" restriction is actually the
browser's built-in security mechanism. Only when a cross-domain request
operation occurs on the browser, the browser will automatically throw the above
error.
Note that this restriction only appears on the browser. If
you use Postman tools to access URLs, there is no "cross-domain"
restriction. After all, Postman doesn't even have a domain name, so there is no
"cross-domain".
CORS
Although browsers have restricted “cross-domain” access
for security reasons, there will inevitably be the need for access to resources
from different sources during development. Therefore, the W3C has developed
CORS (Cross-origin resource sharing) mechanism.
Many people have always thought that CORS = cross-domain.
In fact, CORS is a solution to "cross-domain".
It should be noted that CORS is a "new" protocol
(at least new to the previous IE7), which requires not only browser support,
but also back-end server support.
There is nothing to say about browser support, but whether
the browser version supports it:
Then the back-end server supports it. The server needs to
add the Access-Control-xxx-yyy field to the Response Header, and the browser
can recognize it before it can release the request. For example, the most
common one is to add the return header Access-Control-Allow-Origin and set the
value to the domain name that needs to be allowed.
Simple request VS non-simple request
Browsers divide CORS requests into simple requests and
non-simple requests.
A simple request will automatically add the Origin field
to the HTTP request header when it is sent to indicate which source (protocol +
domain name + port) it is currently, and the server will decide whether to let
it go.
For non-simple requests, an OPTIONS pre-check request will
be sent to the server first, and when it passes, a normal CORS request will be
sent.
For simple requests, the request method is one of the
following three:
·
Head
·
Post
·
Get
And the HTTP request header field cannot exceed the
following fields:
·
Accept
·
Accept-Language
·
Content-Language
·
Last-Event-ID
·
Content-Type
At the same time Content-Type can only have three values:
application/x-www-form-urlencoded corresponds to ordinary
forms
Multipart/form-data corresponding file upload
text/plain corresponds to text sending (generally not very
useful)
As
long as the above conditions are not met, it is a non-simple request. Many
people may naturally think that POST requests are non-simple requests, because
we often see OPTIONS sent first when POST is sent. In fact, because we
generally pass data in JSON format, and the Content-Type is application/json,
such POST requests are non-simple requests.
Access-Control-xxx-yyyy
When
the CORS request is a simple request, the request will detect the following
fields in the returned header:
•
Access-Control-Allow-Credentials: When the request needs to carry cookies, this
field needs to be true to allow cookies to be carried.
•
Access-Control-Expose-Headers: Because the XMLHttpRequest object can only get 6
basic fields: Cache-Control, Content-Language, Content-Type, Expires,
Last-Modified, Pragma. If you want to get other fields, you need to specify
them here.
When the CORS request is a non-simple request, the browser
will first send an OPTIONS preflight request, which will check the following
fields:
• Access-Control-Request-Method: Specify
accessible methods. For non-simple requests, RESTful methods such as PUT,
PATCH, and DELETE may be used, and the server needs to add these method names
as well.
• Access-Control-Request-Headers: Specify
additional information that will be added to the HTTP request header. A very
common scenario is that the backend sometimes puts some environmental
parameters in the request header. If this field is not used to specify the
allowed fields, then "cross-domain" restrictions will appear.
If the OPTIONS request does not pass the server
verification, a normal HTTP request will be returned without the CORS return
information, so the browser will recognize it as "cross-domain".
In summary, when the Console reports an error, you can add
which field to the server's return header.
CORS middleware
No matter for Express or KOA, we don't need to manually
add the above fields anymore. You can add the above fields easily by directly
adding a cors middleware, and it is more elegant to write:
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
JSONP
What about browsers
that do not support CORS? Although it is unlikely at the moment, how do you
solve cross-domain in an era when there is no CORS? The answer is JSONP.
Its principle is also
very simple: Although browsers restrict HTTP cross-domain requests, there are
no restrictions on cross-domain requests for obtaining script tag content.
When we insert a
<script src="xxx.com"> tag, we will send a GET request to get
xxx.com, and there is no "cross-domain" restriction on this GET
request. This method can solve the problem of cross-domain The domain problem.
Server-side
implementation:
1.
2.
3.
4.
前端实现:
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
When the jsonp function is called, a script tag is automatically
created, and the request is placed in scr, and a GET request is automatically
initiated. The server will directly return a string of JavaScript code, and
then the front-end executes this JS code obtained from the server to obtain the
back-end data.
Cross-domain scenarios
"Cross-domain" not only exists in interface access, but
also in the following scenarios:
- The front-end accesses cross-domain URLs. The most common scenario requires the back-end to add the return field of cors
- Micro front end: There may be "cross-domain" operations in resource access between the main application and sub-applications, and cors needs to be added to the sub-application/main application
- Login redirection: It's essentially the same as the first one, but it's not the same at the phenomenon level. For example, when accessing abc.com, some websites will be redirected to their login page passport.abc.com. If passport.abc.com does not have cors set, cross-domain
Summarize
In general, what we often call "cross-domain" is
actually the restrictions imposed by the browser itself when accessing
resources from different sources (protocol + domain name + port).
In the past, developers would use JSONP to solve cross-domain by
generating a script tag and automatically initiating a GET request, but this
method is very insecure and is not recommended.
Up to now, browsers have perfectly supported the CORS mechanism,
just add the corresponding return header Access-Control-xxx-yyy on the server
side. When the browser reports a "cross-domain" error, which field is
missing, just configure which field on the server side.
When developing on the Node side, we can directly use the cors
middleware to configure, instead of handwriting to return the fields in the
header.