关于通信
1.同源策略
源:协议(http/https)+域名(www.baidu.com)+端口(一般默认80) 三个中有一个不一样,就是源不一样,就是跨域
不是同一个源限制
无法获取cookie,localStorage,indexDB
DOM无法获取
AJAX请求不能发送
2.如何创建AJax
//AJAX 可以使网页实现异步更新,整个网页不用空闲等待。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新
XMLHttpRequest对象的工作流程
(1).创建一个XMLHttpRequest对象
var xhr = createxmlHttpRequest();
//考虑兼容,是否支持XMLHttpRequest,
function createxmlHttpRequest() { if (window.ActiveXObject) { return new ActiveXObject("Microsoft.XMLHTTP"); } else if (window.XMLHttpRequest) { return new XMLHttpRequest(); } }(2).使用open设置和服务器的交互信息
method参数可以是GET、POST或PUT。url参数可以是相对URL或绝对URL。这个方法还包括3个可选的参数,是否异步,用户名,密码
xhr.open("method","URL",[asyncFlag],["userName"],["password"])
(3).使用send传送数据,开始和服务器交互
xhr.send(convertData(data))
function convertData(data){
if( typeof data === 'object' ){
var convertResult = "" ;
for(var c in data){
convertResult+= c + "=" + data[c] + "&";
}
convertResult=convertResult.substring(0,convertResult.length-1)
return convertResult;
}else{
return data;
}
}
(4).注册事件
xhr.onreadystatechange = function() { if (xhr.readyState == 4) { if(xhr.status == 200){ ajaxData.success(xhr.response) }else{ ajaxData.error() } } } (5).刷新页面
3.跨域通信的几种方式
(1)jsonp
动态创建<script>标签,然后利用<script>的src 不受同源策略约束来跨域获取数据。
srcz中有一个回调函数callback=hanleFn
function handleFn(response){
//response获取响应数据,只适合get请求
}
同一个主域名下的cookie跨域,如www.baidu.com和yun.baidu.com可以利用cookie的domain设置为.baidu.com,path表示当前cookie生效的目录
不同主域名,就可以使用jsonp
(2)hash
hash#后面的的改变不会刷新页面,search?后面的改变会刷新页面,所以hash可以做跨域通信
a.html首先创建一个隐藏的iframe,iframe的src指向localhost:8081/b.html,这时的hash值就可以做参数传递
b.html收到消息后通过parent.location.hash值来修改a.html 的hash值,从而实现数据传递
由于两个页面不在同一个域下,IE、Chrome不允许修改parent.location.hash的值,所以要借助localhost:8080域名下的一个代理iframe的c.html页面。
//数据直接暴露在了url中,数据容量和类型都有限等
(3)postMessage
在A窗口中内嵌B窗口
<iframe id="iframe" src="http://xx.com/B.html"></iframe>
//在A窗口
var iframeWindow = document.getElementById('iframe').contentWindow;
iframeWindow.postMessage(msg,"http://xx.com/B.html"); //参数一:要传送的消息,参数二:目标源;若指定为”*“,则表示可以传递给任意窗口,指定为”/“,则表示和当前窗口的同源窗口
//在B窗口
window.addEventListener("message", function(e){
if(e.origin === 'http://source.com') {
document.getElementById('msg').innerHTML = e.data;
}
}, false);
(4)websocket
可以后台通知前端,不用前端一直轮询请求,等待后端响应。本身是支持不同源的,是可以跨域的
前端实现
源自阮一峰老师博客
http://www.ruanyifeng.com/blog/2017/05/websocket.html
var ws = new WebSocket("wss://echo.websocket.org"); ws.onopen = function(evt) { console.log("Connection open ..."); ws.send("Hello WebSockets!"); }; ws.onmessage = function(evt) { console.log( "Received Message: " + evt.data); ws.close(); }; ws.onclose = function(evt) { console.log("Connection closed."); };后端的node实现参考
https://github.com/theturtle32/WebSocket-Node
(5)CORS
换句话说CORS是可以跨域的ajax通信
CORS简单请求(simple request)
浏览器自动在头信息之中,添加一个Origin字段(判断本次请求来自哪个源(协议 + 域名 + 端口))。服务器根据这个值,决定是否同意这次请求。
如果Origin指定的域名在许可范围内,服务器返回的响应,会多出几个Access-Control-开头头信息字段
若不在,则会抛出错误,但这种错误无法通过状态码识别,因为HTTP回应的状态码有可能是200。
CORS非简单请求(not-so-simple request)。
非简单请求在正式请求前会发送一个“”预检“”请求,服务器对“预检”做出响应,如果否定则会报错,否则和简单请求一样正常请求

浙公网安备 33010602011771号