1. Why does cross-domain exist?
The browser’s security mechanism is the same origin policy, which prevents malicious web pages from stealing data.
The cookie of A website, if B website can be accessed, B website can pretend to be A user after getting the cookie
The behavior of homologous restriction is
Cookie, LocalStorage, and IndexDB cannot be read. (2) DOM cannot be obtained. (3) AJAX requests cannot be sent.Copy the code
2. How to become cross-domain
Same protocol, same domain name, same port
Cross-domain requests are classified into simple requests and complex requests
A simple request must meet the following conditions
As long as the following two conditions are met, it is a simple request. (1) The request method is one of the following three methods: HEAD GET POST (2) HTTP header does not exceed the following fields: Accept accept-language content-language last-event-id content-type: Application/X-www-form-urlencoded, multipart/form-data, text/plain are limited to three values
If any of the above requirements are not met, it is a complex request
The partial response header for a simple request looks like this
Access-control-allow-origin:
- If it is *, the browser will not send cookies, even if your XHR is set to withCredentials
- Specify the domain
- Dynamic request fields, where the server operation gets header.origin from the request
res.header("Access-Control-Allow-Origin", req.headers.origin);
Copy the code
Access-control-allow-credentials (optional)
This item indicates whether cookies are included in the request
Contains the true
Not included: No field is written
This should be consistent with the withCredentials property in the XmlHttpRequest2 object, which is true when withCredentials is true. When the withCredentials are false, this item is omitted
Access-control-expose-headers (optional)
Additional information available from the getResponseHeader() method in the XmlHttpRequest2 object. In general, the getResponseHeader() method can only get the following information: Cache-Control Content-language Content-type Expires last-Modified PragmaCopy the code
Complex request
A “pre-request” is sent first, and the server needs to return a “pre-reply” as a response.
A pre-request is actually a permission request to the server. The actual request is executed only when the pre-request is successfully returned.
The server return code is usually used with 100
HTTP status code 100: continue Initial request to accept, the client sends the rest
HTTP status code 101: Switching Protocols The server translates compliance with a client’s request to another protocol
The pre-request is sent in the form of OPTIONS, which also contains fields and contains two CORS specific items:
Access-control-request-method – This is the type of actual Request, which can be simple requests like GET, POST, PUT, DELETE, and so on. Access-control-request-headers – This item is a comma-separated list of the Headers used by the complex Request.
3. Master and subdomain names and knowledge points
A.com is a top-level domain name
Bbs.a.com is a subdomain name, also known as a multi-level domain name
Pay attention to
-
CSS reference font cross domain issues
-
Canvas. DrawImage has cross domain problems when drawing links. Set crossorigin to solve the problem
-
CSS styles are not affected by cross-domain issues (questionable)
4. How to solve cross-domain problems
Hash + iframe 4. Window. name + iframe 5. PostMessage 6. Cers-cross-origin Resource Sharing 7. Nginx proxy 8. Nodejs middleware proxy 9. WebSocket protocol Cross domain
JSONP
In order to reduce the load of the Web server, we separate static resources such as JS, CSS and IMG to another server with an independent domain name, and then load static resources from different domain names through corresponding tags in the HTML page, which is allowed by the browser. Based on this principle, we can dynamically create script. Request a reference url to achieve cross-domain communication
this.$http.jsonp('http://www.domain2.com:8080/login', {
params: {},
jsonp: 'handleCallback'
}).then((res) = > {
console.log(res);
})
Copy the code
Document.domain + iframe cross domain
This solution applies only to cross-domain scenarios where the primary domain is the same and the subdomains are different
Implementation principle: two pages through JS forced document.domain as the base of the primary domain, to achieve the same domain
1.) parent window :(www.domain.com/a.html)
<iframe id="iframe" src="http://child.domain.com/b.html"></iframe>
<script>
document.domain = 'domain.com';
var user = 'admin';
</script>
Copy the code
2.) sub-window :(child.domain.com/b.html)
<script>
document.domain = 'domain.com';
// Get the variables in the parent window
alert('get js data from parent ---> ' + window.parent.user);
</script>
Copy the code
Location. hash + iframe cross-domain
Implementation principle: A wants to communicate with B across domains, which is achieved through the middle page C. Three pages, different fields use iframe location.hash to transfer values, the same fields directly js access to communicate.
A domain: A.html -> B domain: B.html -> A domain: C.HTML, A and B different domain can only hash value one-way communication, B and C are also different domain can only one-way communication, but C and A are the same domain, so C can access all objects on A page through parent. Parent.
1.) A.HTML (www.domain1.com/a.html)
<iframe id="iframe" src="http://www.domain2.com/b.html" style="display:none;"></iframe>
<script>
var iframe = document.getElementById('iframe');
// Pass hash values to B.html
setTimeout(function() {
iframe.src = iframe.src + '#user=admin';
}, 1000);
// callback methods open to homologous C.HTML
function onCallback(res) {
alert('data from c.html ---> ' + res);
}
</script>
Copy the code
2.) B.HTML (www.domain2.com/b.html)
<iframe id="iframe" src="http://www.domain1.com/c.html" style="display:none;"></iframe>
<script>
var iframe = document.getElementById('iframe');
// listen for hash values from A.html and pass them to C.HTML
window.onhashchange = function () {
iframe.src = iframe.src + location.hash;
};
</script>
Copy the code
3.) C. HTML (www.domain1.com/c.html)
<script>
// Listen for hash values from B.html
window.onhashchange = function () {
// Return the result by manipulating the javascript callback of the same domain A.html
window.parent.parent.onCallback('hello: ' + location.hash.replace('#user='.' '));
};
</script>
Copy the code
Window. name + iframe cross domain
The window.name attribute is unique in that the name value persists across different pages (and even different domain names) and supports very long name values (2MB).
1.) A.HTML (www.domain1.com/a.html)
var proxy = function(url, callback) {
var state = 0;
var iframe = document.createElement('iframe');
// Load the cross-domain page
iframe.src = url;
// The onload event fires twice, the first time the cross-domain page is loaded and the data is stored in window.name
iframe.onload = function() {
if (state === 1) {
// After the second onload(syndomain proxy page) succeeds, the data in syndomain window.name is read
callback(iframe.contentWindow.name);
destoryFrame();
} else if (state === 0) {
// After the first onload succeeds, switch to the same-domain proxy page
iframe.contentWindow.location = 'http://www.domain1.com/proxy.html';
state = 1; }};document.body.appendChild(iframe);
// After the data is retrieved, the iframe is destroyed to free memory; This also ensures security (not accessed by other fields frame JS)
function destoryFrame() {
iframe.contentWindow.document.write(' ');
iframe.contentWindow.close();
document.body.removeChild(iframe); }};// Request cross-domain B page data
proxy('http://www.domain2.com/b.html'.function(data){
alert(data);
});
Copy the code
2.) proxy. HTML: www.domain1.com/proxy… Intermediate proxy page, same domain as A.HTML, content is empty.
3.) B.HTML (www.domain2.com/b.html)
<script>
window.name = 'This is domain2 data! ';
</script>
Copy the code
Summary: The SRC attribute of iframe is used to pass the data from the outfield to the local region. The cross-domain data is passed from the outfield to the local region by the window.name of iframe. This is a neat way to circumvent the browser’s cross-domain access restrictions, but it’s also a secure operation.
PostMessage cross-domain
PostMessage is an API in HTML5 XMLHttpRequest Level 2, and is one of the few window properties that can operate across domains. It can be used to solve the following problems: A.) data transfer of the page and the new window it opens b.) message transfer between multiple Windows c.) page and nested iframe message transfer (game box) d.) cross-domain data transfer of the three scenarios above
Usage: The postMessage(data, Origin) method takes two arguments data: the HTML5 specification supports any primitive type or replicable object, but some browsers only support strings, so it’s best to serialize the argument with json.stringify (). Origin: protocol + host + port number. The value can also be set to “*”, which indicates that it can be sent to any window. If you want to specify the origin of the current window, set it to “/”.
1.) A.HTML (www.domain1.com/a.html)
<iframe id="iframe" src="http://www.domain2.com/b.html" style="display:none;" ></iframe> <script> var iframe = document.getElementById('iframe'); iframe.onload = function() { var data = { name: 'aym' }; / / to send cross domain data domain2 iframe. ContentWindow. PostMessage (JSON. Stringify (data), 'http://www.domain2.com'); }; Window. addEventListener('message', function(e) {alert('data from domain2 --> '+ e.data); }, false); js </script>Copy the code
2.) B.HTML (www.domain2.com/b.html)
<script>
// Receive data from domain1
window.addEventListener('message'.function(e) {
alert('data from domain1 ---> ' + e.data);
var data = JSON.parse(e.data);
if (data) {
data.number = 16;
// Send it back to domain1
window.parent.postMessage(JSON.stringify(data), 'http://www.domain1.com');
}js
}, false);
</script>
Copy the code
Cross-domain Resource Sharing (CORS)
For common cross-domain requests, only access-Control-allow-origin is required on the server. This parameter is not required on the front end. If cookie is required, access-Control-allow-origin is required on both the front and back ends.
Note that due to the restriction of the same-origin policy, the cookie read is the cookie of the domain where the cross-domain request interface resides, not the current page. Nginx reverse proxy sets proxy_cookie_domain and cookieDomainRewrite (NodeJs).
Currently, all browsers support this functionality (IE8+ : IE8/9 requires the use of XDomainRequest objects to support CORS), and CORS has become a mainstream cross-domain solution.
The front set
axios.defaults.withCredentials = true
Copy the code
Nginx configuration resolves iconFONT across domains
Browser cross-domain access js, CSS, and img conventional static resources are the same-origin policy permission, but iconfont font file (eot | otf | the vera.ttf | woff | SVG) exception, at this time in nginx server to add the following configuration static resources.
location / {
add_header Access-Control-Allow-Origin *;
}
Copy the code
2. Nginx reverse proxy interfaces cross domains
Cross-domain principle: The same Origin policy is a security policy of the browser, not a part of the HTTP protocol. The server invokes the HTTP interface only using THE HTTP protocol, and does not execute JS scripts. There is no need for the same origin policy, so there is no crossing problem.
Nginx configure a proxy server (domain name and domain1 the same, different port) as a jumper, reverse proxy access to domain2 interface, and can incidentally modify the cookie in the domain information, convenient for the current domain cookie writing, cross-domain login.
Nginx configuration:
#proxy server {listen 81; server_name www.domain1.com; location / { proxy_pass http://www.domain2.com:8080; # reverse proxy proxy_cookie_domain www.domain2.com www.domain1.com; # change cookie domain name index index.html index.htm; # When accessing Nignx with middleware proxy interface such as Webpack-dev-server, there is no browser participation, so there is no source restriction. Add_header access-Control-allow-origin http://www.domain1.com; * add_header access-control-allow-credentials true; * add_header access-control-allow-credentials true; }}Copy the code
Cross domain of VUE framework (1 cross domain)
Cross domain using node + Webpack + webpack-dev-server agent interface. In the development environment, since the Vue rendering service and the interface proxy service are the same as Webpack-dev-server, there is no need to set headers cross-domain information between the page and proxy interface.
Webpack.config.js part configuration:
module.exports = {
entry: {},
module: {},...devServer: {
historyApiFallback: true.proxy: [{
context: '/login'.target: 'http://www.domain2.com:8080'.// Proxy cross-domain target interface
changeOrigin: true.secure: false.// Used when the agent reports an error with some HTTPS service
cookieDomainRewrite: 'www.domain1.com' // The value can be false, indicating no change}].noInfo: true}}Copy the code
The WebSocket protocol is cross-domain
Reference [segmentfault.com/a/119000001…