What is cross-domain? Cross-domain solution (the top priority)

Cross-domain I didn’t understand it before, but I will understand it slowly. The front-end we learn is probably part of the website domain name interaction.

 

 

1. Why do cross-domain problems occur

Due to the browser's same-origin policy restrictions. Same origin policy (Sameorigin policy) is a convention, it is the core and most basic security function of the browser. If the same origin policy is missing, the normal functions of the browser may be affected. It can be said that the Web is built on the basis of the same-origin policy, and the browser is only an implementation of the same-origin policy. The same-origin policy prevents the JavaScript scripts of one domain from interacting with the content of another domain. The so-called homology (that is, in the same domain) means that two pages have the same protocol, host and port

Second, what is cross-domain

When any one of the protocol, domain name, and port of a request url is different from the current page url, it is cross-domain

Current page url URL of the requested page Whether cross-domain the reason
http://www.test.com/ http://www.test.com/index.html no Same source (the same protocol, domain name, and port number)
http://www.test.com/ https://www.test.com/index.html Cross-domain Different protocols (http/https)
http://www.test.com/ http://www.baidu.com/ Cross-domain The main domain name is different (test/baidu)
http://www.test.com/ http://blog.test.com/ Cross-domain Different subdomains (www/blog)
http://www.test.com:8080/ http://www.test.com:7001/ Cross-domain The port number is different (8080/7001)

Three, non-homologous restriction

[1] Unable to read Cookies, LocalStorage and IndexedDB of non-same-origin webpages

[2] Unable to access the DOM of non-same-origin web pages

[3] Unable to send AJAX request to non-same source address

Four, cross-domain solutions

[1] Set document.domain to solve the problem of not being able to read cookies from non-same-origin webpages

Because the browser checks whether two pages are of the same origin through the document.domain property, the two pages can share cookies as long as the same document.domain is set (this scheme is limited to cross-domains with the same primary domain and different subdomains) Application scenarios.)

 
  1. // 两个页面都设置

  2. document.domain = 'test.com';

[2] Cross-document communication API: window.postMessage()

Call the postMessage method to implement the parent window http://test1.com to send a message to the child window http://test2.com (the child window can also send messages to the parent window through this method)

It can be used to solve the following problems:

  • Data transfer between pages and new windows opened
  • Message passing between multiple windows
  • Page and nested iframe messaging
  • Cross-domain data transfer in the above three scenarios
// 父窗口打开一个子窗口

var openWindow = window.open('http://test2.com', 'title');


// 父窗口向子窗口发消息(第一个参数代表发送的内容,第二个参数代表接收消息窗口的url)

openWindow.postMessage('Nice to meet you!', 'http://test2.com');

调用message事件,监听对方发送的消息


// 监听 message 消息

window.addEventListener('message', function (e) {

console.log(e.source); // e.source 发送消息的窗口

console.log(e.origin); // e.origin 消息发向的网址

console.log(e.data); // e.data 发送的消息

},false);

【3】JSONP

JSONP 是服务器与客户端跨源通信的常用方法。最大特点就是简单适用,兼容性好(兼容低版本IE),缺点是只支持get请求,不支持post请求。

核心思想:网页通过添加一个<script>元素,向服务器请求 JSON 数据,服务器收到请求后,将数据放在一个指定名字的回调函数的参数位置传回来。

①原生实现:


<script src="http://test.com/data.php?callback=dosomething"></script>

// 向服务器test.com发出请求,该请求的查询字符串有一个callback参数,用来指定回调函数的名字


// 处理服务器返回回调函数的数据

<script type="text/javascript">

function dosomething(res){

// 处理获得的数据

console.log(res.data)

}

</script>

② jQuery ajax:


$.ajax({

url: 'http://www.test.com:8080/login',

type: 'get',

dataType: 'jsonp', // 请求方式为jsonp

jsonpCallback: "handleCallback", // 自定义回调函数名

data: {}

});

③ Vue.js


this.$http.jsonp('http://www.domain2.com:8080/login', {

params: {},

jsonp: 'handleCallback'

}).then((res) => {

console.log(res);

})

【4】CORS

CORS is the abbreviation for Cross-Origin Resource Sharing. It is a W3C standard and a fundamental solution for cross-origin AJAX requests.

1. Ordinary cross-domain request: only need to set Access-Control-Allow-Origin on the server side

2. Cross-domain request with cookie: both front and back ends need to be set

[Front-end settings] Determine whether there is a cookie according to the xhr.withCredentials field

① Native ajax

var xhr = new XMLHttpRequest(); // IE8/9需用window.XDomainRequest兼容


// 前端设置是否带cookie

xhr.withCredentials = true;


xhr.open('post', 'http://www.domain2.com:8080/login', true);

xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');

xhr.send('user=admin');


xhr.onreadystatechange = function() {

if (xhr.readyState == 4 && xhr.status == 200) {

alert(xhr.responseText);

}

};

② jQuery ajax 


$.ajax({

url: 'http://www.test.com:8080/login',

type: 'get',

data: {},

xhrFields: {

withCredentials: true // 前端设置是否带cookie

},

crossDomain: true, // 会让请求头中包含跨域的额外信息,但不会含cookie

});


③vue-resource

Vue.http.options.credentials = true

④ axios 

axios.defaults.withCredentials = true

[Server Settings]

The server-side support for CORS is mainly carried out by setting Access-Control-Allow-Origin. If the browser detects the corresponding settings, it can allow Ajax to conduct cross-domain access.

① Java background

/*

* 导入包:import javax.servlet.http.HttpServletResponse;

* 接口参数中定义:HttpServletResponse response

*/


// 允许跨域访问的域名:若有端口需写全(协议+域名+端口),若没有端口末尾不用加'/'

response.setHeader("Access-Control-Allow-Origin", "http://www.domain1.com");


// 允许前端带认证cookie:启用此项后,上面的域名不能为'*',必须指定具体的域名,否则浏览器会提示

response.setHeader("Access-Control-Allow-Credentials", "true");


// 提示OPTIONS预检时,后端需要设置的两个常用自定义头

response.setHeader("Access-Control-Allow-Headers", "Content-Type,X-Requested-With");

② Nodejs后台


var http = require('http');

var server = http.createServer();

var qs = require('querystring');


server.on('request', function(req, res) {

var postData = '';


// 数据块接收中

req.addListener('data', function(chunk) {

postData += chunk;

});


// 数据接收完毕

req.addListener('end', function() {

postData = qs.parse(postData);


// 跨域后台设置

res.writeHead(200, {

'Access-Control-Allow-Credentials': 'true', // 后端允许发送Cookie

'Access-Control-Allow-Origin': 'http://www.domain1.com', // 允许访问的域(协议+域名+端口)

/*

* 此处设置的cookie还是domain2的而非domain1,因为后端也不能跨域写cookie(nginx反向代理可以实现),

* 但只要domain2中写入一次cookie认证,后面的跨域接口都能从domain2中获取cookie,从而实现所有的接口都能跨域访问

*/

'Set-Cookie': 'l=a123456;Path=/;Domain=www.domain2.com;HttpOnly' // HttpOnly的作用是让js无法读取cookie

});


res.write(JSON.stringify(postData));

res.end();

});

});


server.listen('8080');

console.log('Server is running at port 8080...');

③ PHP background

 
  1. <?php

  2. header("Access-Control-Allow-Origin:*");

④ Apache needs to use the mod_headers module to activate the HTTP header settings, which is activated by default. You only need to add the following content to the configuration of <Directory>, <Location>, <Files> or <VirtualHost> in the Apache configuration file

Header set Access-Control-Allow-Origin *

 

Guess you like

Origin blog.csdn.net/qq_37430247/article/details/112245952