Web应用跨域通信解决方案。

一.本地测试,搭建虚拟服务器环境

            讲到跨域通信,我们首先要了解什么是跨域?跨域大致的意思就是,比如:www.XXX.com域名下的js是不能操作www.YYY.com域名下的对象或者元素。了解了跨域的大概意思之后,接下来为了能够在本地演示跨域的操作,我们首先要在本地的电脑上搭建虚拟服务器环境。我的电脑上用的是PHPnow(PHPnow是一个集成Apache+PHP+MySQL环境套件包).具体操作如下:

       ①安装PHPnow(安装比较简单就不介绍了)

       ②打开PHPnow的安装页面,运行PnCp文件。

                  

        ③选择编号执行相应的操作(标号0)

                   

        ④添加主机(我之前已经添加了两个)

                   

          

        ⑤本地域名映射,打开hosts文件:路径C:\Windows\System32\drivers\etc,添加本地映射

                     


              ⑤在hosts中添加之前你写的域名。

                  

         ⑥打开浏览器输入你写的域名,虚拟服务器搭建完毕。

       

                       

二.同域通信操作

        同域文档之间的访问方式,在ajax这一栏目下我会在博客中列出。目前先说几个:iframe,window.open,ajax等。那同域文档之间的通信,js是否可以随便操作同域文档所在的窗口对象呢?答案请看示例。

1.iframe内嵌同域名文档。

下面是1iframe.html文档:

<span style="font-size:18px;"><body>
<input type='button' value='点击我,改变同域底下的iframe嵌套页面的背景色' id='in1'/>
<iframe src='1.iframe.html' id='iframe'></iframe>
</body></span>

<span style="font-size:18px;">window.onload = function(){
	var oInput = document.getElementById('in1');
	var oMyIfram = document.getElementById('iframe');
	
	oInput.onclick = function(){
		//如果我们要操作一个iframe里面的dom元素,首先要获取到iframe引入的页面的window
		oMyIfram.contentWindow.document.body.style.background = '#c0c0c0';	
	};
};</span>

下面是1.iframe.html文档:
<span style="font-size:18px;"><body>
我是www.chenming.com底下的1.iframe.com的内容
<input type='button' value='点击改变被嵌套页面的背景色' id='in'/>
</body></span>
<span style="font-size:18px;">window.onload = function(){
	var oIn = document.getElementById('in');
	
	oIn.onclick = function(){
		//window parent top
		parent.document.body.style.background = 'green';	
	};	
};</span>
       说明:1iframe.html中通过iframe内嵌了同域名底下的文档1.iframe.html,也就是在1iframe.html的页面中嵌入了另一个窗口,那么1iframe.html中想操作1.iframe.html所在窗口,首先获取iframe对象oMyIframe,接着调用contentWindow
<pre name="code" class="javascript"><font size="4">oMyIfram.contentWindow//获取到<span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;">1.iframe.html所在窗口</span></span></span>对象。</font>

 那么1.iframe.html所在页面也可以操作1iframe.html页面。 
1.iframe.html页面他有自身的window页面,父级页面parent,顶级页面top,层级是Window<=parent<=top; 
那我们调用parent这个窗口对象就可以操作1iframe.html页面页面了。 

2.window.open打开同域名文档。
下面是1window.html文档:

<span style="font-size:18px;"><input type='button' value='点击打开新的页面' />
<input type='button' value='点击改变打开新的页面的背景色'</span>
<span style="font-size:18px;">window.onload = function(){
	var aInput = document.getElementsByTagName('input');
	var newWindow = null;
	
	aInput[0].onclick = function(){
		//window.open 返回被打开窗口的window对象
		newWindow = window.open('1.window.html','_blank');	
	};	
	
	aInput[1].onclick = function(){
		newWindow.document.body.style.background = 'green';	
	};
};</span>
下面是1.window.html文档:

<span style="font-size:18px;">我是www.chenming.com底下的1.window.html的内容
<input type='button' value='点击改变被打开页面的背景色' /></span>
<span style="font-size:18px;">window.onload = function(){
	var oInput = document.getElementsByTagName('input')[0];
	oInput.onclick = function(){
		//window.opener : 通过window.open方法打开当前页面的窗口window
		window.opener.document.body.style.background = '#c0c0c0';	
	};
};</span>
       说明:1window.html通过window.open()打开了新的页面1.window.html。这个open打开之后返回一个窗口对象。这个窗口对象就是1.window.html的页面,那我们就可以利用这个对象来操作1.window.html的页面元素了。相反的,如果想要1.window.html的页面操作1window.html,那我们首先要获取到他的窗口对象,可以通过窗口对象下的一个方法来获取:window.opener;

3.ajax访问同域名文档。

         ajax同域名访问也是没有问题的,因为在我的ajax原理与封装( http://blog.csdn.net/dreamchenming/article/details/52174014 )这一块说过,这里就不再赘述了。

三.跨域通信操作

        之前我们在ajax栏目的博客中介绍过同域底下文档的通信,那ajax可否进行跨域通信呢?先来看一个ajax是跨域请求的例子:

下面是http://www.chenming.com/ajax.html文档:

<input type='button' value='ajax跨域请求资源' id='btn'/>
window.onload = function(){
	var oBtn = document.getElementById('btn');
	
	oBtn.onclick = function(){
		
/*
在标准浏览器下,XMLHttpRequest对象已经是升级版本,支持了更多的特性,可以跨域了
但是,如果想实现跨域请求,还需要后端的相关配合才可以
		
XMLHttpRequest : 增加很多功能,他也不推荐使用onreadystatechange这个事件来监听,推荐使用onload
		
XDomainRequest : IE如果想实现跨域请求,则需要使用另外一个对象去实现 
<pre name="code" class="javascript">*/	
/*var xhr = new XMLHttpRequest();xhr.onreadystatechange = function(){if(xhr.readyState == 4){if(xhr.status == 200){alert(xhr.responseText);}}}xhr.open('get','http://www.chenming1.com/1.php',true);xhr.send();*/var xdr = new XDomainRequest();xdr.onload = function(){alert(this.responseText);};xdr.open('get','http://www.chenming1.com/1.php',true);xdr.send();};};

 
下面是http://www.chenming1.com/1.php文档: 

<?php
    echo 'hello word!';
      说明:当我们这样通过ajax跨域访问的时候,浏览器console出现了下面的情况:


上述提示缺少了‘Access-Control-Allow-Origin’这个头信息,那我们是不是就不能通过ajax跨域访问了,当然不是,我们只要让后台文件配合就可以跨域通信了,方式如下:

<?php
header('Access-Control-Allow-Origin:http://www.chenming.com');//这是允许访问该资源的域
	echo 'hello word!';
         ajax只要后台配合就可以跨域访问,那我们通过iframe方式能不能跨域请求呢?一试便知,看下面的例子:

下面是www.chenming.com/2iframe.com文档:

<input type='button' value='点击我,改变同域底下的iframe嵌套页面的背景色' id='in1'/>
<iframe src='http://www.chenming1.com/2.iframe.html' id='iframe'></iframe>
window.onload = function(){
	var oInput = document.getElementById('in1');
	var oMyIfram = document.getElementById('iframe');
	
	oInput.onclick = function(){
		//当本页面和包含页面不在同一个域名下的时候,这样操作就会有跨域操作安全限制问题。
		//oMyIfram.contentWindow.document.body.style.background = '#c0c0c0';	
	}
};
下面是www.chenming1.com/2.iframe.com文档:

我是www.chenming1.com底下的2.iframe.com的内容
<input type='button' value='点击改变被嵌套页面的背景色' id='in'/>
window.onload = function(){
	var oIn = document.getElementById('in');
	
	oIn.onclick = function(){
		parent.postMessage('2','http://www.chenming.com/2iframe.html');	
	};	
};
       说明:结果我们发现通过iframe跨域通信受限制了,也就是之前操作同域的方式来操作跨域是行不通的。

                                    

那我们有没有其他方式来解决跨域通信的问题呢?html5中提供了postMessage的方法可以帮助我们解决这个跨文档通信的问题。一起来看看是怎么用的吧。

下面是www.chenming.com/2iframe.com文档:

window.onload = function(){
	var oInput = document.getElementById('in1');
	var oMyIfram = document.getElementById('iframe');
	
	oInput.onclick = function(){
		//当本页面和包含页面不在同一个域名下的时候,这样操作就会有跨域操作安全限制问题。
		//oMyIfram.contentWindow.document.body.style.background = '#c0c0c0';	
		
		/*
			postMessage : 可以通过这个方法给另外一个窗口发送信息
		
			接收消息的窗口的window对象.postMessage();
		*/
		oMyIfram.contentWindow.postMessage('1','http://www.chenming1.com/1.iframe.html');
		
	};
	
	window.addEventListener('message',function(ev){
		if(ev.data == '2'){
			window.document.body.style.background = '#c0c0c0';	
		}	
	},false);
};
下面是www.chenming1.com/2.iframe.com文档:

window.onload = function(){
	var oIn = document.getElementById('in');
	
	oIn.onclick = function(){
		parent.postMessage('2','http://www.chenming.com/2iframe.html');	
	};	
	
	
	/*
		message : 当窗口接收到通过postMessage发送过来的数据的时候触发
	*/
	window.addEventListener('message',function(ev){
		//alert(ev.origin+'发送了'+ev.data);
		if(ev.data == '1'){
			window.document.body.style.background = 'green';
		}
	})
};
当然了,postMessage是发送一个数据给另一个页面,另一个页面一直去监听message事件。而不是一个页面直接去操作另一个页面的元素,所以这个方式可以让两个页面进行协调,比如,这个页面传入什么值的时候,另一个页面发生相应的变化即可。除了ajax(后台文件配合加头文件),postMessage等跨域通信解决方式之外,还有没有其他的方式呢?后续我会在ajax栏目的博客中写另一种跨域请求的解决方式:那就是JSONP( JSON WITH PADDING ),这个方式就是通过script标签内嵌跨域页面,然后通过一个回调函数将数据传输给我们,具体的到时候在ajax栏目的博客中去看。

四.ajax实现无刷新上传

         这一块介绍一下ajax是如何解决无刷新上传的,具体的我就直接上代码了,代码里面也有解说。

后台上传php文件

<?php
header('Content-type:text/html; charset="utf-8"');
$upload_dir = 'uploads/';

if(strtolower($_SERVER['REQUEST_METHOD']) != 'post'){
	exit_status(array('code'=>1,'msg'=>'错误提交方式'));
}

if(array_key_exists('file',$_FILES) && $_FILES['file']['error'] == 0 ){
	
	$pic = $_FILES['file'];
	
	if(move_uploaded_file($pic['tmp_name'], $upload_dir.$pic['name'])){
		exit_status(array('code'=>0,'msg'=>'上传成功','url'=>$upload_dir.$pic['name']));
	}
	
}
echo $_FILES['file']['error'];
exit_status(array('code'=>1,'msg'=>'出现了一些错误'));

function exit_status($str){
	echo json_encode($str);
	exit;
}
?>
上传页面:

<input type='file' id='myFile' />
<input type='button' value='上传' id='btn'/>
<div id='box'>
	<div id='progress'></div>
    <div id='scale'>0%</div>
</div>
window.onload = function(){
	var oMyFile = document.getElementById('myFile');
	var oBtn = document.getElementById('btn');
	var oBox = document.getElementById('box');	
	var oProgress = document.getElementById('progress');
	var oScale = document.getElementById('scale');
	
	oBtn.onclick = function(){
		
		//console.log(oMyFile.files[0]);
		
		var xhr = new XMLHttpRequest();
		
		xhr.onload = function(){
			console.log('上传成功');	
		};
		
		xhr.open('post','post_file.php',true);
		xhr.setRequestHeader('X-Request-With', 'XMLHttpRequest');
		
		var oFormData = new FormData();	//通过FormData来构建提交数据
		oFormData.append('file', oMyFile.files[0]);
		
		xhr.send(oFormData);
		
		var oUpload = xhr.upload;
		
		oUpload.onprogress = function(ev){
			var ev = ev || event;
			console.log(ev.loaded + ':'+ev.total);
			oBox.style.display = 'block';
			//ev.total   ev.loaded;
			var iScale = Math.floor(ev.loaded/ev.total)*100;
			oProgress.style.width = iScale*2 + 'px';
			oScale.innerHTML = iScale + '%';
		};
		
			
	};
};
效果图:





  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值