postMessage
window.postMessage()是HTML5的一个接口,专注实现在不同窗口不同页面的跨域通信。 用法:postMessage(data,origin) 参数:
- data:html5规范支持任意基本类型或可复制的对象,但部分浏览器只支持字符串,所以传参时最好用JSON.stringify()序列化。
- origin:协议+主机+端口号,也可以设置为"*",表示可以传递给任意窗口,如果要指定和当前窗口同源的话设置为"/"。
- a.html:(www.dotest1.com/a.html)
<iframe id="iframe" src="http://www.dotest2.com/b.html" style="display:none;"></iframe>
<script>
var iframe = document.getElementById('iframe');
iframe.onload = function() {
var data = {
name: 'aym'
};
// 向dotest2传送跨域数据
iframe.contentWindow.postMessage(JSON.stringify(data), 'http://www.dom2.com');
};
// 接受domain2返回数据
window.addEventListener('message', function(e) {
alert('data from dotest2 ' + e.data);
}, false);
</script>
- b.html:(www.dotest2.com/a.html)
<script>
// 接收domain1的数据
window.addEventListener('message', function(e) {
alert('data from dotest1 ---> ' + e.data);
var data = JSON.parse(e.data);
if (data) {
data.number = 16;
// 处理后再发回domain1
window.parent.postMessage(JSON.stringify(data), 'http://www.domain1.com');
}
}, false);
</script>
CORS
cors全称是“跨域资源共享”(Cross-origin resource sharing),cors请求有两种请求,简单请求和非简单请求。 只要同时满足以下两大条件,就属于简单请求。
- 请求方法是以下三种方法之一
- HEAD
- GET
- POST
- HTTP的头信息不超出以下几种字段
- Accept
- Accept-Language
- Content-Language
- Last-Event-ID
- Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain
普通请求只需要在服务端设置Access-Control-Allow-Origin即可,也就是告诉什么站点是被允许的。前端什么也不用干只需要正常的发送请求就好。
res.writeHead(200, {
'Access-Control-Allow-Origin': 'http://www.do1.com', // 允许访问的域(协议+域名+端口)
});
但是如果需要带cookie的话,前后端都需要进行设置
前台
- 原生ajax
var xhr = new XMLHttpRequest(); // IE8/9需用window.XDomainRequest兼容
// 前端设置是否带cookie
xhr.withCredentials = true;
xhr.open('post', 'http://www.dotest2.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);
}
};
- jQueryajax:
$.ajax({
...
xhrFields: {
withCredentials: true // 前端设置是否带cookie
},
crossDomain: true, // 会让请求头中包含跨域的额外信息,但不会含cookie
...
});
- vue框架
Vue.http.options.credentials = true
后台
- Node
// 跨域后台设置
res.writeHead(200, {
'Access-Control-Allow-Credentials': 'true', // 后端允许发送Cookie
'Access-Control-Allow-Origin': 'http://www.dotest1.com', // 允许访问的域(协议+域名+端口)
/*
* 此处设置的cookie还是dotest2的而非dotest1,因为后端也不能跨域写cookie(nginx反向代理可以实现),
* 但只要dotest2中写入一次cookie认证,后面的跨域接口都能从dotest2中获取cookie,从而实现所有的接口都能跨域访问
*/
'Set-Cookie': 'l=a123456;Path=/;Domain=www.dotest2.com;HttpOnly'
// HttpOnly的作用是让js无法读取cookie
});
非简单请求:如果请求方法是PUT、DELETE,或者Content-type的类型为applicetion/json的。使用非简单请求 会发出一次预检测,返回码是204,预检测通过才会发送真正的请求
- Node
var allowCrossDomain = function(req, res, next) {
res.header('Access-Control-Allow-Origin', 'http://localhost:63342');
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
res.header('Access-Control-Allow-Headers', 'Content-Type,accept,X-Custom-Header');
res.header('Access-Control-Allow-Credentials', 'true');
next();
};
- 前端
var url = 'http://www.domain2.com:8080/login';
var xhr = new XMLHttpRequest();
xhr.open('PUT', url, true);
xhr.setRequestHeader('X-Custom-Header', 'value');
xhr.send()
上边代码中,HTTP请求方法是PUT,并且发送了一个自定义头信息X-Custom-Header。浏览器发现这是一个非简单请求 ,就会发出一个预检请求,要求服务器确认可以这样请求。
代理
跨域原理: 同源策略是浏览器的安全策略,不是HTTP协议的一部分。服务器端调用HTTP接口只是使用HTTP协议,不会执行JS脚本,不需要同源策略,也就不存在跨越问题。 **实现思路:**通过nginx配置一个代理服务器(域名与dotest1相同,端口不同)做跳板机,反向代理访问dotest2接口,并且可以顺便修改cookie中domain信息,方便当前域cookie写入,实现跨域登录。
1. nginx具体配置
proxy服务器
server {
listen 81;
server_name www.domain1.com;
location / {
proxy_pass http: //www.domain2.com:8080; #反向代理
proxy_cookie_domain www.domain2.com www.domain1.com;#修改cookie里域名
index index.html index.htm;
#当用webpack - dev - server等中间件代理接口访问nignx时, 此时无浏览器参与, 故没有同源限制, 下面的跨域配置可不启用
add_header Access - Control - Allow - Origin http: //www.domain1.com; #当前端只跨域不带cookie时,可为*
add_header Access - Control - Allow - Credentials true;
}
}
- 前端代码示例
var xhr = new XMLHttpRequest();
// 前端开关:浏览器是否读写cookie
xhr.withCredentials = true;
// 访问nginx中的代理服务器
xhr.open('get', 'http://www.domain1.com:81/?user=admin', true);
xhr.send();
- 后台Nodejs
2. Nodejs中间件代理插件 这篇有详细说明详见
WebSocket协议跨域
WebSocket protocol是HTML5一种新的协议。它实现了浏览器与服务器全双工通信,同时允许跨域通讯,是server push技术的一种很好的实现。 原生WebSocket API使用起来不太方便,我们使用Socket.io,它很好地封装了webSocket接口,提供了更简单、灵活的接口,也对不支持webSocket的浏览器提供了向下兼容。
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!