Ucenter中跨域访问的分析

记得在之前的一篇名为《UCENTER 会员同步登录通讯原理》的文章中,我说到了,在所有的应用中要想向Ucenter的服务器端发送数据,都调用到了一个函数(uc_api_post)。其实这个函数里面的学问蛮大的。他涉及的东西很多,我们一一来分析:
ucenter客户端向服务器端发送请求的原理解析:
当我们一个应用(UCHome)向Ucenter发送一个同步登陆或者同步退出时,该应用(UCHome)是怎么想用
服务器端发送数据请求的呢?
以同步登陆为例,当我们调用函数uc_user_synlogin(),此函数调用函数uc_api_post(),并且传递相关的mod的值和action的值,我们通过找到该函数知道,此函数调用的有两个函数:uc_api_requestdata()和uc_fopen2(),函数uc_api_requestdata是组织一些带参数的URL形式,函数uc_fopen2()最终调用uc_fopen()通过fsockopen()套接字实现打开远程文件的功能。
这个过程中最主要的功能就是这个套接字的使用了。我们来看下这个函数:

functionuc_fopen($url,$limit = 0, $post= '', $cookie = '',$bysocket = FALSE, $ip = '',$timeout = 15, $block= TRUE) {
        $return= '';
        $matches= parse_url($url);//解析URL
	!isset($matches['host']) && $matches['host'] ='';//获得主机名称
	!isset($matches['path']) && $matches['path'] ='';//当前文件名
	!isset($matches['query']) && $matches['query'] =''; //参数
	!isset($matches['port']) && $matches['port'] ='';//端口
	$host= $matches['host'];
	$path= $matches['path'] ?$matches['path'].($matches['query'] ? '?'.$matches['query'] :'') : '/';
	$port= !empty($matches['port']) ?$matches['port'] : 80;
	//预处理要写入远程文件的HEAD头信息和参数$post;
	if($post) {
		$out= "POST $path HTTP/1.0\r\n";
		$out.= "Accept: */*\r\n";
		//$out .= "Referer: $boardurl\r\n";
		$out.= "Accept-Language: zh-cn\r\n";
		$out.= "Content-Type: application/x-www-form-urlencoded\r\n";
		$out.= "User-Agent: $_SERVER[HTTP_USER_AGENT]\r\n";
		$out.= "Host: $host\r\n";
		$out.= 'Content-Length: '.strlen($post)."\r\n";
		$out.= "Connection: Close\r\n";
		$out.= "Cache-Control: no-cache\r\n";
		$out.= "Cookie: $cookie\r\n\r\n";
		$out.= $post;
	}else {
		$out= "GET $path HTTP/1.0\r\n";
		$out.= "Accept: */*\r\n";
		//$out .= "Referer: $boardurl\r\n";
		$out.= "Accept-Language: zh-cn\r\n";
		$out.= "User-Agent: $_SERVER[HTTP_USER_AGENT]\r\n";
		$out.= "Host: $host\r\n";
		$out.= "Connection: Close\r\n";
		$out.= "Cookie: $cookie\r\n\r\n";
        }
	//使用fsockopen打开远程连接
	$fp= @fsockopen(($ip? $ip : $host), $port,$errno, $errstr,$timeout);
	if(!$fp) {
		return'';//note $errstr : $errno \r\n
	}else {
		stream_set_blocking($fp,$block);//让程序无阻塞
		stream_set_timeout($fp,$timeout);   //超时设置
		@fwrite($fp,$out);
		$status= stream_get_meta_data($fp);  //读取数据流
		if(!$status['timed_out']) {//判断是否超时(超时时该值为空,否则为1)
		      while(!feof($fp)) {
				if(($header= @fgets($fp)) && ($header== "\r\n" ||  $header == "\n")) {
					break;
				}
		      }
		 
			$stop= false;
			while(!feof($fp) && !$stop) {
				//获取服务器端传输来的数据(这里为一些JS串)
				$data= fread($fp, ($limit== 0 || $limit > 8192 ? 8192 : $limit));
				$return.= $data;
				if($limit) {
					$limit-= strlen($data);
					$stop= $limit <= 0;
				}
	                }
                  }
		@fclose($fp);
		return$return;
	}
}


当客户端向服务器端请求时,会调用套接字发送head请求头信息,并且带上客户端发送给服务器端的数据,服务器接受这些数据之后经过一系列的处理之后返回一些JS字符串。这些字符串数据被打开的套接字fsockopen()接收并且存储在$return变量中,之后便是一步步的返回给最初调用的函数如:uc_user_synlogin(),这就是为什么我们把这个函数的返回值输出来是一串JS字符串了。
这样子 整个Ucenter的跨域访问就彻底结束了。。。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值