用CBrother实现的一个http代理服务器,解决跨域问题

用CBrother实现的一个http代理服务器,解决跨域问题


之前做一个需求,需要帮用户管理几百个路由器的IP、用户名、密码,在网页上点击一个按钮后就要直接进入路由器并自动登录。
寻找了好多方案,大部门路由器都有跨域问题,非常头大。
后面想着必须把路由器的页面代理到同一个地址下面,然后在嵌到到ifram里面才能操作它的账号密码框与登录按钮,还是用cbrother解决了这个问题,记录一下。

import CBHttp.code

var g_selfurl = "192.168.1.100";//服务器自己的IP,所有中转都要把服务器IP换成对端IP

class ProxyAction	//中转响应类
{
	function DoAction(request,respon)
	{
		respon.addProperty("Access-Control-Allow-Origin","*");//添加跨域权限
		var clientReq = new HttpClientRequest();	//请求目标的客户机对象
		clientReq.setMethod(request.getMethod());
		
		var targeturl = null;		
		var cookieCnt = request.getCookieCount();//添加cookie
		if(cookieCnt > 0)
		{			
			for(var i = 0 ; i < cookieCnt ; i++)
			{
				var cookie = request.getCookie(i);
				if(cookie.getName() == "targeturl")//自己记录的目标IP不要添加
				{
					targeturl = cookie.getValue();
					print "targeturl:" + targeturl;
					continue;
				}
				clientReq.addCookie(cookie);
			}			
		}
		
		if(targeturl == null)
		{
			respon.write("not find ip!");
			respon.flush();
			return;
		}
		
		var propertyMap = request.getAllProperty();
		
		propertyMap.begin();
	
		//添加所有头
		do
		{
			var key = propertyMap.getKey();
			var value = propertyMap.getValue();	   
			value = strreplace(value,g_selfurl,targeturl);//替换服务器地址为对方地址			
			clientReq.addProperty(key,value);
		} while(propertyMap.next());		

		var url = "http://" + targeturl + "/";
		if(request.getUrl() != "index.html")
		{
			url += request.getUrl();
		}
		
		var allparm = request.getAllParm();//添加url后面的参数
		if(allparm.size() > 0)
		{
			var isFirst = true;
			url += "?";
			allparm.begin();
			do
			{
				if(!isFirst)
				{
					url += "&";
					isFirst = false;
				}
				
				url += allparm.getKey();
				url += "=";
				url += allparm.getValue();
			}while(allparm.next());
		}
		
		print url;
		clientReq.setUrl(url);
		var data = request.getData();
		if(data != null)
		{
			clientReq.addData(data);
		}
		
		
		var clientRespon = clientReq.flush();//发起请求		
		
		respon.setStatus(clientRespon.getStatus());
		
		var clientMap = clientRespon.getAllProperty();
		
		//把对方返回头返回给浏览器
		if(clientMap.size() > 0)
		{
			clientMap.begin();
			do
			{
			   var key = clientMap.getKey();
			   var value = clientMap.getValue();	   
			  // print key + ":" +  value;
			   respon.addProperty(key,value);
			   
			} while(clientMap.next());		
		}
		
		//把对方返回的cookie返回给浏览器
		var resCookieCnt = clientRespon.getCookieCount();
		for(var i = 0 ; i < resCookieCnt ; i++)
		{
			var cookie = clientRespon.getCookie(i);
			respon.addCookie(cookie);
		}				
		
		//返回数据
		data = clientRespon.getData();
		respon.write(data);
		respon.flush();		
	}
}

class LoginAction
{
	function DoAction(request,respon)
	{
		respon.addProperty("Access-Control-Allow-Origin","*");
		var targeturl = request.getParm("ip");//获取要代理的地址
		
		//如果地址写成自己了不支持
		if(strfind(targeturl,g_selfurl) != null || strfind(targeturl,"127.0.0.1") != null)
		{
			respon.write("ip err!");
			respon.flush();			
			return;
		}		
		
		respon.addCookie(new Cookie("targeturl",targeturl));
		
		var file = new File(GetRoot() + "webroot/login.html");//返回自己的网页,这个就和代理的网页在同一个域里面了,把它嵌到ifram里面想怎么操作就怎么操作
		var size = file.size();
		var readbuf = file.read(size);
		
		respon.write(readbuf);
		respon.flush();
		file.close();
	}
}

function main(parm)
{
	var httpServer = new HttpServer();
	httpServer.closeFileService();	//关闭文件下载服务,请求文件也要中转
	httpServer.setThreadCount(50);
	httpServer.setOutTime(5);
	httpServer.addAction("proxy.cb",new ProxyAction());//添加代理接口
	httpServer.addAction("remotelogin.cb",new LoginAction());//请求开始的接口
	httpServer.set404Action("proxy.cb");//设置404接口名字,这样除了remotelogin.cb之外的所有连接都会走到这里
	//httpserver.setHttpsCertFile("e:/aa.crt","e:/aa.key");  //也支持https,只是你要设置自己的证书
	httpServer.startServer(80);	
	
	while(1)
	{
		Sleep(1000);
	}	
}

页面代码

<html lang="zh-CN">
	<head>	
		<title>代理</title> 
		<iframe id="mywin" frameborder="0" align="left" width="1024" height="1024">
			加载中
        </iframe>
	   <script>			
			var iframe = document.getElementById("mywin");
			iframe.src = "http://192.168.1.100";
			iframe.onload = function()
			{
				iframe = document.getElementById("mywin");
				var targetdiv = iframe.contentDocument.getElementById("main");
				var html = "<div>我修改了你的网页<div>" + targetdiv.innerHTML;
				targetdiv.innerHTML = html;
			}
	   </script>
	</head>
</html>

这样你再浏览器输入自己服务器IP http://192.168.1.100/remotelogin.cb?ip=www.cbrother.net
用CBrother实现的一个http代理服务器,解决跨域问题
网页被我们修改了。
其实也可以不嵌入到ifram里面,在中转的时候抓住html添加进自己的js代码也是完全可以的。