如何在iframe之间共享数据

近期开始工作了,接手的第一个项目是已近开发完成的,后期有些bug和操作方式要进行修改,我主要负责修改操作方式。

原来系统使用的是用下拉框的方式来选择项目,这种方式简单方便,但是当数据很多的时候,不仅会降低系统运行效率,在上千条的数据中选择记录基本是一件不可能的事情,针对这个问题,我们有两种解决方法::第一种,使用autocomplete插件,用户数据少量数据,可以把数据补全。第二种,专门弹出 一层来选择需要选择的内容,弹出层可以分页、搜索。

我们选择了后一种方法,这就涉及到了iframe之间数据共享的问题。

实现的主要思路如下(点击图片查看大图)

iframe之间共享数据

主框架页弹出两个框架页,子框架页通过主框架页来共享数据,项目使用了ligerUI。

主框架页

	// 流程中弹出窗处理
	function popWindow(url, title, width, height) {
        $.ligerDialog.open({
			url : url,
          	height : height,
          	title : title,
          	width : width,
          	close : function(dialog){
				dialog.frame.$("#classForm").validationEngine("hideAll");
            },
            buttons : [{
              	text : '保存',
              	onclick : function(item, dialog) {
                	var carForm = dialog.frame.$("#classForm");
                	if(carForm.validationEngine("validate")){
                  		//验证通过 保存表单内容
                  		dialog.frame.saveInfo();
                  		// 关闭窗口
                  		dialog.close();
               		}
              	}
            }]
		});
	}

	var monitorEquipId = "";
	var monitorEquip = "";

	function setMonitorEquipInfo(id, name) {
		monitorEquipId = id;
		monitorEquip = name;
	}

	function getMonitorEquipId() {
		return monitorEquipId;
	}

	function getMonitorEquip() {
		return monitorEquip;
	}
 

信息填写页

// 选择监测设备
	function showSelectEquip() {
		var id = $$('#monitorequipid').val();
		var name = $$('#monitorequip').val();
		var config = {
			url : "/baseinfo/abilityChooseAction!chooseEquip.action?polltype="
										+ parent.polltype,
			title : "选择监测设备",
			height : 500,
			width : 600,
			buttons : [ {
				text : "确定",
				onclick : function(item, dialog) {
                                        // 点击确定后,从主框架页获取数据
					$$('#monitorequipid').val(parent.getMonitorEquipId());
					$$('#monitorequip').val(parent.getMonitorEquip());
					dialog.close();
				}
			} ]
		};
                 //调用主框架页的弹出
		parent.popInfoWindow(config);
	}

信息选择页面

	function chooseOk(id, name) {
		parent.setMonitorEquipInfo(id, name);
	}

jsp File browser 1.2(jsp网马)解决中文乱码问题

jsp File browser 1.2这个工具还是比较好用的,支持简单的文件操作,作者在写的时候没有考虑到在非英文系统下的乱码问题,导致很多操作都无法实现,近期正好有空,就做了乱码修复。

简单来看下:

作者在写的时候直接把编码写成了ISO-8859-1,压根没想中文正常显示的想法吧。。

我们可以全部设定编码为UTF-8来解决乱码问题,但是他在代码里都只直接使用request.getParameter(“key”)方式来进行数据的获取的,如果是get提交数据上去的话,不用说,数据肯定都是不正常的,而且作者使用post方式提交文件路径(文件路径的URL在返回的时候进行了URLEncode,但是没有指定编码)。

简单想了下解决办法:

1.针对post方法提交数据大部分都是正常的,不做处理

2.针对get提交的普通数据,要进行返回到字节码,再重新编码的过程(服务器用iso8859错误解码了)。

3.URLEncode过的数据,使用post传回来,这个要进行url解码。

具体实施:

编码统一使用UTF-8,URLEncode的时候指定编码。URLDecode的时候也使用指定编码。

使用一张HashMap来保持进行乱码处理后的数据,然后要获取数据的时候从hashmap里面去取。

	// 自定义获取对象方法
	static String getParameter(String name){
		String[] obj = (String[])hm.get(name);
		if(obj!=null && obj.length>=1){
			return obj[0];
		}
		return null;
	}
	static String[] getParameterValues(String name){
		String[] values = (String[]) hm.get(name);
		return values;
	}

       // 定义个hashmap,来放所有的数据
	hm = new HashMap();
	// 如果是post的话直接拷贝
	if(request.getMethod()=="POST"){
		Enumeration enumeration = request.getParameterNames();
		while(enumeration.hasMoreElements()){
			String nameStr = enumeration.nextElement().toString();
			String values[] = request.getParameterValues(nameStr);
			if("selfile".equals(nameStr)){
				//因为这个数据是在服务器编码 ,传给浏览器,然后浏览器post回来的
				for(int i=0;i<values.length;i++){
					values[i] = URLDecoder.decode(values[i],ENCODE);
				}
			}
			hm.put(nameStr,values);
		}
	}else{
		// 遍历全部参数转码  iso-8859-1  到 utf-8 通过url提交 被服务器以iso-8859-1解码了
		Enumeration enumeration = request.getParameterNames();
		while(enumeration.hasMoreElements()){
			String nameStr = enumeration.nextElement().toString();
			String values[] = request.getParameterValues(nameStr);
			// 遍历转换
			for(int i=0;i<values.length;i++){
				values[i] = new String(values[i].getBytes("iso-8859-1"),ENCODE);
			}
			hm.put(nameStr,values);
		}
	}
// 使用的时候 这么使用
request.setAttribute("dir", getParameter("dir"));

这么修改以后添加删除,命令行的使用都可以支持中文了。
点击下载:adminfix

独辟蹊径解决win7 64位windows installer无法启动的问题。

独辟蹊径解决win7 64位windows installer无法启动的问题。
近期安装软件的时候,软件无法安装提示windows installer服务无法使用。
图片1
运行services.msc进去一看 windows installer 无法启动,提示访问被拒绝。
网上找了各种方法:
1.修改注册表
2.重装windows installer(这个是扯淡,4.5完全是xp用的,win7用的版本还没出呢)
3.用系统盘进行恢复(咱没盘)

我试了试用命令行的方式启动,依旧是拒绝访问。
怀疑是misexec.exe文件被病毒感染了,提取了一个新的文件覆盖,问题依旧。

又怀疑访问被拒绝可能是和UAC和NTFS文件权限有关,改了半天,无果而终。

网上逛的时候,发现有人windows installer服务的选项丢失,好奇点了注册表进去。
发现新大陆了。
在HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\msiserver下面
发现有ImagePath填写的就是服务的启动方式。
话不多说,直接把msiexec.exe文件从system32里面拷贝到了别的地方,将ImagePath改成了新的位置。
修改路径
这个时候再去服务里面看的时候,路径已经改成了新路径了。启动一下,成功了!
回services.msc检查
赶紧去安装软件,使用一切正常~各位要遇到这个问题不妨试试我这个办法~

JavaScript,调用函数的5种方法

这篇文章详细的介绍了Javascript中各种函数调用的方法及其原理,对于理解JavaScript的函数有很大的帮助!

JavaScript,调用函数的5种方法
一次又一次的,我发现,那些有bug的Javascript代码是由于没有真正理解Javascript函数是如何工作而导致的(顺便说一下,许多那样的代码是我写的).JavaScript拥有函数式编程的特性, 当我们选择面对它的时候,这将成为我们前进的阻碍.
作为初学者,我们来测试五种函数调用的方法,从表面来看我们会认为那些函数与C#中函数的作用非常相似,但是我们一会儿可以看到还是有非常重要的不同的地方的,忽视这些差异无疑会导致难于跟踪的bug。首先让我们创建一个简单的函数,这个函数将在将在下文中使用,这个函数仅仅返回当前的this的值和两个提供的参数.

 

1
2
3
4
5
<script type="text/javascript">
function makeArray(arg1, arg2){
    return [ this, arg1, arg2 ];
}
</script>

最常用的方法,但不幸的,全局的函数调用
当我们学习Javascript时,我们了解到如何用上面示例中的语法来定义函数。
,我们也知道调用这个函数非常的简单,我们需要做的仅仅是:

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
makeArray('one', 'two');
// => [ window, 'one', 'two' ]
Wait a minute. What's that window
alert( typeof window.methodThatDoesntExist );
// => undefined
alert( typeof window.makeArray);
// =>
window.makeArray('one', 'two');
// => [ window, 'one', 'two' ]

我说最普遍的调用方法是不幸的是因为它导致我们声明的函数默认是全局的.我们都知道全局成员不是编程的最佳实践.这在JavaScript里是特别的正确,在JavaScript中避免使用全局的成员,你是不会为之后悔的.

JavaScript函数调用规则1

在没有通过明确所有者对象而直接调用的函数中,如myFunction(),将导致this的值成为默认对象(浏览器中的窗口)。

函数调用
让我们现在创建一个简单的对象,使用 makeArray函数作为它的一个方法,我们将使用json的方式来声明一个对象,我们也来调用这个方法

 

 

1
2
3
4
5
6
7
8
9
10
11
12
//creating the object
var arrayMaker = {
    someProperty: 'some value here',
    make: makeArray
};
//invoke the make() method
arrayMaker.make('one', 'two');
// => [ arrayMaker, 'one', 'two' ]
// alternative syntax, using square brackets
arrayMaker['make']('one', 'two');
// => [ arrayMaker, 'one', 'two' ]

 
看到这里的不同了吧,this的值变成了对象本身.你可能会疑问原始的函数定义并没有改变,为何它不是window了呢.好吧,这就是函数在JSavacript中传递的方式,函数在JavaScript里是一个标准的数据类型,确切的说是一个对象.你可以传递它们或者复制他们.就好像整个函数连带参数列表和函数体都被复制,且被分配给了 arrayMaker里的属性make,那就好像这样定义一个 arrayMaker:

 

1
2
3
4
5
6
var arrayMaker = {
    someProperty: 'some value here',
    make: function (arg1, arg2) {
        return [ this, arg1, arg2 ];
    }
};

 

JavaScript函数调用规则2

在一个使用方法调用语法,像 obj.myFunction()或者 obj[‘myFunction’](),这时this的值为obj

这是事件处理代码中bug的主要源头,看看这些例子

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<input type="button" value="Button 1" id="btn1"  />
<input type="button" value="Button 2" id="btn2"  />
<input type="button" value="Button 3" id="btn3"  onclick="buttonClicked();"/>
<script type="text/javascript">
function buttonClicked(){
    var text = (this === window) ? 'window' : this.id;
    alert( text );
}
var button1 = document.getElementById('btn1');
var button2 = document.getElementById('btn2');
button1.onclick = buttonClicked;
button2.onclick = function(){   buttonClicked();   };
</script>

 

点击第一个按钮将会显示”btn”因为它是一个方法调用,this为所属的对象(按钮元素) 点击第二个按钮将显示”window”因为 buttonClicked是被直接调用的(不像 obj.buttonClicked().) 这和我们第三个按钮,将事件处理函数直接放在标签里是一样的.所以点击第三个按钮的结果是和第二个一样的.
使用像jQuery的JS库有这样的优点,当在jQuery里定义了一个事件处理函数,JS库会帮助重写this的值以保证它包含了当前事件源元素的引用,

//使用jQuery
$(‘#btn1’).click( function() {
alert( this.id ); // jQuery ensures ‘this’ will be the button
});

jQuery是如何重载this的值的呢?继续阅读
另外两个:apply()和call()
你越多的使用JavaScript的函数,你就越多的发现你需要传递函数并在不同的上下文里调用他们,就像Qjuery在事件处理函数里所做的一样,你往往经常需要重置this的值.记住我告诉你的,在Javascript中函数也是对象,函数对象包含一些预定义的方法,其中有两个便是apply()和call(),我们可以使用它们来对this进行重置.

 

1
2
3
4
5
var gasGuzzler = { year: 2008, model: 'Dodge Bailout' };
makeArray.apply( gasGuzzler, [ 'one', 'two' ] );
// => [ gasGuzzler, 'one' , 'two' ]
makeArray.call( gasGuzzler,  'one', 'two' );
// => [ gasGuzzler, 'one' , 'two' ]

这两个方法是相似的,不同的是后面的参数的不同,Function.apply()是使用一个数组来传递给函数的,而Function.call()是将这些参数独立传递的,在实践中你会发现apply()在大多数情况下更方便.

JSavacript函数调用规则3

如果我们想在不复制函数到一个方法而想重载this的值的时候,我们可以使用 myFunction.apply( obj ) 或 myFunction.call( obj ).

构造器
我不想深入研究在Javascript中类型的定义,但是在此刻我们需要知道在Javascript中没有类,而且任何一个自定义的类型需要一个初始化函数,使用原型对象(作为初始化函数的一个属性)定义你的类型也是一个不错的主义,让我们来创建一个简单的类型
//声明一个构造器

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function ArrayMaker(arg1, arg2) {
    this.someProperty = 'whatever';
    this.theArray = [ this, arg1, arg2 ];
}
// 声明实例化方法
ArrayMaker.prototype = {
    someMethod: function () {
        alert( 'someMethod called');
    },
    getArray: function () {
        return this.theArray;
    }
};
var am = new ArrayMaker( 'one', 'two' );
var other = new ArrayMaker( 'first', 'second' );
am.getArray();
// => [ am, 'one' , 'two' ]

 

一个非常重要并值得注意的是出现在函数调用前面的new运算符,没有那个,你的函数就像全局函数一样,且我们创建的那些属性都将是创建在全局对象上(window),而你并不想那样,另一个话题是,因为在你的构造器里没有返回值,所以如果你忘记使用new运算符,将导致你的一些变量被赋值为 undefined.因为这个原因,构造器函数以大写字母开头是一个好的习惯,这可以作为一个提醒,让你在调用的时候不要忘记前面的new运算符.
带着这样的小心,初始化函数里的代码和你在其他语言里写的初始化函数是相似的.this的值将是你将创建的对象.

Javascript函数调用规则4

当你将函数用作初始化函数的时候,像MyFunction(),Javascript的运行时将把this的值指定为新建的对象.

我希望理解各种函数调用方式的不同会使你的Sjavacript代码远离bugs,有些这样的bug会确保你总是知道this的值是避免他们第一步。

转自:http://lhb25.cnblogs.com/

Chrome 常用键盘快捷键

Chrome 常用键盘快捷键

如果你是初次使用Chrome,有可能你会感觉Chrome好像缺少了某些东西似的,没错,为了让用户获得最大的浏览界面,Chrome连工具栏都缩成一个小小的按钮了。别以为这样会很不方便,Chrome提供了大量的键盘快捷方式,让你轻松打开你想要的功能。

窗口和标签页快捷键

 

Ctrl+N 打开新窗口
Ctrl+T 打开新标签页
Ctrl+Shift+N 在隐身模式下打开新窗口
Ctrl+O,然后选择文件 在谷歌浏览器中打开计算机上的文件
按住 Ctrl 键,然后点击链接 从后台在新标签页中打开链接,但您仍停留在当前标签页中
按住 Ctrl+Shift 键,然后点击链接 在新标签页中打开链接,同时切换到新打开的标签页
按住 Shift 键,然后点击链接 在新窗口中打开链接
Alt+F4 关闭当前窗口
Ctrl+Shift+T 重新打开上次关闭的标签页。谷歌浏览器可记住最近关闭的 10 个标签页。
将链接拖动到标签页内 在指定标签页中打开链接
将链接拖动到两个标签页之间 在标签页横条的指定位置建立一个新标签页,在该标签页中打开链接
Ctrl+1 到 Ctrl+8 切换到指定位置编号的标签页。您按下的数字代表标签页横条上的相应标签位置。
Ctrl+9 切换到最后一个标签页
Ctrl+Tab 或Ctrl+PgDown 切换到下一个标签页
Ctrl+Shift+Tab Ctrl+PgUp 切换到上一个标签页
Ctrl+W 或 Ctrl+F4 关闭当前标签页或弹出式窗口
Alt+Home 打开主页

地址栏快捷键

在地址栏,进行下列操作之一:

 

键入搜索字词 使用默认搜索引擎进行搜索
键入网址中”www.”和”.com”之间的部分,然后按 Ctrl+Enter 为您在地址栏中输入的内容添加”www.”和”.com”,然后打开网址
键入搜索引擎关键字或网址,按 Tab 键,然后键入搜索字词 使用与关键字或网址相关联的搜索引擎进行搜索。如果谷歌浏览器可以识别您要使用的搜索引擎,则会提示您按 Tab 键。
F6 或 Ctrl+L 或 Alt+D 选中网址区域中的内容
键入网址,然后按Alt+Enter 键 在新标签页中打开网址

打开谷歌浏览器各功能的快捷键

 

Ctrl+B 打开和关闭书签栏
Ctrl+Shift+B 打开书签管理器
Ctrl+H 查看”历史记录”页
Ctrl+J 查看”下载”页
Shift+Escape 查看任务管理器
Shift+Alt+T 将焦点设置在工具栏上。使用键盘上的向右和向左箭头,可导航至工具栏上的不同按钮。

网页快捷键

 

Ctrl+P 打印当前页
Ctrl+S 保存当前页
F5 重新加载当前页
Esc 停止加载当前页
Ctrl+F 打开”在网页上查找”框
点击鼠标中键或滚轮(只在谷歌浏览器测试版(只有英文版)中可用) 激活自动滚动。当您移动鼠标时,网页会根据鼠标的移动方向自动滚动。
Ctrl+F5 或 Shift+F5 重新加载当前页,但忽略缓存内容
按住 Alt 键,然后点击链接 下载链接
Ctrl+G 或 F3 查找与您在”在网页上查找”框中输入的内容相匹配的下一个匹配项
Ctrl+Shift+G 或 Shift+F3 查找与您在”在网页上查找”框中输入的内容相匹配的上一个匹配项
Ctrl+U 查看源代码
将链接拖动到书签栏 将链接加入书签
Ctrl+D 将当前网页加入书签
Ctrl++,或者按住 Ctrl 键并向上滚动鼠标滚轮 放大网页上的所有内容
Ctrl+-,或者按住 Ctrl 键并向下滚动鼠标滚轮 缩小网页上的所有内容
Ctrl+0 将网页上的所有内容都恢复到正常大小

文字快捷键

 

选中内容,然后按 Ctrl+C 键 将内容复制到剪贴板
将光标置于文本字段中,然后按 Ctrl+V 或Shift+Insert 键 从剪贴板粘贴当前内容
将光标置于文本字段中,然后按 Ctrl+Shift+V 键 从剪贴板粘贴当前内容的纯文本部分
选中文字字段中的内容,然后按 Ctrl+X 或Shift+Delete 键 删除内容并将其复制到剪贴板

最佳网页宽度及其兼容实现方法

1.设计网页的时候,确定宽度是一件很苦恼的事。 

以jb51.net为例,根据Google Analytics的统计,半年多以来,访问者的屏幕分辨率一共有81种。最小的分辨率是122×160,这应该是手机;最大的分辨率是3360×1050,天知道是什么设备。 

一张网页要在大小如此悬殊的各种屏幕上,都呈现令人满意的效果,难度可想而知。举例来说,一张400px宽的图片,在800px的屏幕上会占据50%的宽度,而在1920px的屏幕上(Windows Vista的流行设置),只占据20%。 
2. 

目前,常见的屏幕分辨率宽度大概有6种:800px,1024px,1280px,1440px,1680px和1920px。其中,1024px最常见,但是随着大屏幕显示器的流行,更高的分辨率正变得越来越多。 

常见的解决方法有两种: 

第一种:用javascript根据不同的客户端分辨率,选择css样式表文件,具体的做法可以看这里。 

第二种:采用弹性布局(Fluid Width Layout),实现网页宽度的自适应。 

第一种方法的优点是,可以根据不同屏幕分辨率,采用完全不同的布局,缺点是要设计和维护多张样式表,比较麻烦。第二种方法只采用一张样式表,比较省事。 

下文就根据css-tricks上的解决方案,讨论如何实现第二种方法,实际上是很简单的。

3.

首先,网页的缺省宽度,确定为满足1024px宽度的显示器。这不仅因为1024×768是现在最常见的分辨率,还因为这个宽度对网页最合适:1)它放得下足够的内容,足够三栏的布局;2)单行文字不宜太长,1024px已是极限,否则容易产生阅读疲劳;3)在当前的互联网带宽条件下,网页难以采用大分辨率所要求的大尺寸图片。

其次,网页宽度会在780px-1260px的范围内,自动变化,即最小不小于780px,最大不超过1280px。

最后,对于更大的分辨率,网页内容会自动居中。

4.

下面就是CSS文件的写法,只要4行。需要注意的是,这几行的语句都针对整个页面,即body标签或者最外层的那个div区域。

margin: 10px auto;

这一行保证了网页在任何分辨率下,都会居中。

min-width: 780px;
max-width: 1260px;

这二行规定了网页的最小和最大宽度。注意,IE6不支持这二行,即它们在IE6中是无效的。

width:expression(document.body.clientWidth < 782? “780px” : document.body.clientWidth > 1262? “1260px” : “auto”);

这一行是针对IE6的解决方法。它采用了CSS表达式,也可以通过javascript实现。

另外,如果想让内层的各个区块也自动伸缩,它们的宽度可以采用百分比的形式,比如:

#div-left{
width:50%;
}

#div-right{
width:50%;
}

最后的效果和源码下载请查看这里。通过变动浏览器窗口的大小,可以发现网页在780px-1260px的范围内会自动伸缩。

5.

最后,建议大家平时使用计算机的时候,不要盲目采用高分辨率,意义不大。

Source:http://www.jb51.net/web/22867.html

15个截图工具分享

 

浏览器插件/扩展类:

Save as image – 一个小巧的插件,可以让你轻松在Firefox中截取到网页,框架或是任何你想要的部分。

下载地址: http://www.zzx8.com/html/s15199.html

Pearl Crescent Page Saver-截图功能和Save as image相仿,可以把图片保存为jpg或png格式。它还可以自动把截图缩放到一个合适的尺寸。

下载地址: http://www.zzx8.com/html/s15200.html

Picnik for Firefox- 直接到截图传送到Picnik进行裁剪与编辑。

 

下载地址: http://www.zzx8.com/html/s15201.html

Snissa- 一个小巧的截图插件,功能比较简单。

官方地址: http://www.snissa.com

Screengrab!- 可以选择截取整个网页(包括屏幕没有显示出来的部分),目前可视网页或者连同Firefox窗口一并截取。甚至还能用鼠标框选截图范围。

 

下载地址: http://www.zzx8.com/html/s15202.html

ieSnapshotter- 唯一一个为IE截图准备的插件,可以生成截图或缩略图片。

下载地址: http://www.zzx8.com/html/s15203.html

软件类:

SnagIt- 对它没有什么多说的了,应该是截图业的霸主了吧。适合对截图有各种要求的变态级截图达人。

 

下载地址: http://www.zzx8.com/html/s15204.html

FastStone Capture- 又是一款强大的截图工具。通过一个小巧的浮动控制面板完成捕捉活动窗口、活动对象、矩形区域、手绘区域、全屏幕、滚动窗口等任务。麻雀虽小,五脏俱全。

 

下载地址: http://www.zzx8.com/html/s12278.html

WebShot- 一个可以将网页或整个网站拍成照片或缩略图的工具。通过其强大的命令行工具可以自动对多个页面进行抓拍,调整图像大小等。

 

下载地址: http://www.zzx8.com/html/s12277.html

PrintKey- 替代你键盘上的Print Screen SysRq键并赋予它更多的功能。

 

下载地址: http://www.zzx8.com/html/s15207.html

基于网络类:

WebShotsPro- 你想要做的仅仅是输入你想要截图的网站地址。当然,在得到结果之前你可能会排上很长时间的队。毕竟很多人都对这个傻瓜式截图工具有爱。

官方地址: http://www.webshotspro.com

Thumbalizr- 和上面的一样,仅仅输入地址就可以完成截图。但它会提供多种分辨率的截图供你选择。唯一的问题是,这网站经常抽风。

官方地址: http://www.thumbalizr.com

转-gae翻墙 hyk-proxy

关于GAE,说得已经够多了,在其上搭建个人私用代理服务器,本博也已经介绍过 。哥就是厚道,强大的GAE之上,越来越多的专业人士开始发力,code.google.com托管的源码项目已经不计其数,其中,如果你有心的话,肯定能找到相当多可用的proxy相关项目。

Hyk-proxy-server就是其中之一,我经过一番尝试,在GAE上又成功搭建起一台代理服务器。废话不多说了,本博文就详细介绍一下如何在GAE上利用Hyk-proxy-server搭建翻墙梯。

简单介绍一下Hyk-proxy-server,它是通过RPC来实现高性能的web proxy。基于目前实现的机制,将来还可以实现暴露更多GAE特有功能,实现为一个远程的GAE lib,而不仅仅作为web proxy。目前支持HTTP/XMPP方式完成web proxy功能——原理不多说了,开工。

 

再次强调GAE

每次提到GAE,总有人莫名其妙,不知道这是啥玩意儿。这次重复解析一下,GAE是Google App Engine(字面意思为Google 程序引擎)的首字母缩写。以后本博仍然按照惯例,对Google App Engine一律以GAE代称——在本博的tag标签则是

GAE是Google提供的一项免费而强大的服务,简单来说,就是Google依托本身的服务器、技术和带宽资源,免费给用户提供的免费服务器——可以看作是特殊的WEB服务器,支持Python和Java编程语言。

GAE官方地址:猛击此处进入

GAE简单介绍:猛击此处进入

GAE程序汇集:猛击此处进入

那么,对普通google用户来说,如何获取并使用GAE呢?

首先,你需要已经有(或者现在注册)一个Gmail账号。然后以此登录Google,并注册一个App Engine账号(点此进入注册),注册过程详解如下:

进入https://appengine.google.com/之后,首先会要求你用Gmail账号登录,如下图

 

登录之后,自动转向Application注册页面,如下图

 

接下来的页面,要求你用手机短信激活GAE账号,如下图

友情提示:我已经注册过两个账号,确认绝不收费,一分钱都不会收

 

需要提醒的只有一点,手机号码的格式应该这样:+86 13888888888

如果格式不对,下一次会提醒你重新输入。点击“send”按钮后跳转到下一页面,此时等待收取手机短信中包含的激活码即可。一般情况下,十分钟之内应该可以收到短信,如果过时仍未收到,在当前页面,点击“try sending it again”链接,重新获取即可——通常不会收不到。如下图,收到之后填入表单,提交

 

提交完成之后,GAE账号即被激活,然后就可以创建新的应用程序了。

以Hyk-Proxy-Server为例,说明如何在GAE创建新应用

激活GAE账号之后,转入“My Applications”页面,点击“Create an Application”新建应用,如下图

 

顺便说一句,一个Gmail账户最多可以创建十个应用。

进入下一步,填写新应用的必要信息,如下图

 

记住上图中填写的第一处,比如添加应用名称为fuckgfw,则fuckgrw即是你的Appid(记住Appid这个词,即应用的编号),而fuckgfw.appspoft.com则是应用的服务器地址。

点击提交之后,即成功创建了一个新的应用,所有的应用管理,可以点击应用名称,进入控制面板进行管理。诸如权限设置/免费还是收费/CPU Time/带宽情况等,都可以详细设置,这里不多说;

如何在新应用上传自己的Hyk-Proxy-server

1,准备工作,先下载相关的代码和工具。

HYK是运行在JAVA平台上的,所以要下载Java,猛击此处进入JAVA官方网站下载;

然后下载GAE的编译环境SDK,猛击此处进入SDK下载,注意要下载for java的版本(以前提到过的AppProxy搭建,则是下载for python版本)——这里提供直接下载地址——点此右键另存为

接着下载Phk-proxy的服务端和客户端,猛击此处进入Phk-proxy官方下载地址。需要注意的是,它的服务端和客户端是分开的,两个包都要下。服务端是hyk-proxy-server-0.8.rc1.zip,客户端是hyk-proxy-client-0.8rc1.zip;

最后,为了方便,尤其是对命令行管理方式不感冒的朋友,下载一个专用于GAE上传代码的工具appcfgwrapper,猛击此处进入工具官方页面,最新的版本是0.2.0

到此为止,你应该下载了5个文件,包括Java,SDK,Phk-proxy-server,phk-proxy-client和app上传工具;

2,安装工具及上传代码

第一步,首先安装Java,非常简单,不多说;

第二步,把下载得到的SDK解压,得到的应该是类似appengine-java-sdk-1.3.3.1的文件夹;

第三步,分别解压hyk的server端和client端,得到两个文件夹;

第四步,解压下载得到的appcfgwrapper;

现在,除了安装到系统中的Java,你应该得到了四个文件夹,如下图

 

接下来,是正式开始往GAE上传代码建立应用:

首先,打开AppCfgWrapper-0.2.0文件夹,找到appcfgwrapper.jar文件,双击运行,如下图

 

稍等片刻,程序被运行,界面如下图所示

 

说明:该填写的地方我在上图都标示出来了

1.前面提到过的Appid,前面举的例子是fuckgfw;

2.版本ver保持为1不变即可;

3.Application,点击浏览按钮,在本地计算机中定位到hyk-proxy-server-0.8.0rc1war;

4.填写Gmail账号以及密码;

填写完毕之后,点击“Add”按钮,添加到任务列表中。

接下来,在列表中选择新建的任务,然后点击“Deploy”按钮,server端代码将被上传到GAE中。

在最下面的详情框中,最后如果你看到success或者finish字样,说明已经上传完毕,服务端搭建好了。

现在,你可以在浏览器地址栏中键入 fuckgfw.appspot.com,回车,如果能看到如下一行

hyk-proxy 0.8.0rc1 server is running!

很明显,代理服务器的服务端已经成功运行了,接下来就要配置本地客户端以启用代理了。

配置hyk-proxy的本机客户端以启用代理

首先,打开hyk-proxy-client-0.8.0rc1文件夹,定位到bin目录下的startgui.bat文件,如下图

 

双击运行之后,会弹出CMD命令行窗口,以及客户端GUI界面,如下图

 

现在,点击“Config”配置按钮,稍等片刻(Java运行真有点慢),弹出配置界面,如下图

 

上图中可以看到,作者搭建的示例程序还在,删掉即可。

点击New按钮把自己的Appid添加上,如下图

 

说明:只需添加AppID即可,用户名和密码不用填,填写了可能会出现错误,需要手动检查配置文件;

填写完毕,OK,回到前一个配置页面,点击最下面的应用按钮“Apply”,回到客户端界面。

此时,点击右侧最上面的Start按钮,让本机客户端连接GAE上的服务端。如果连接成功,则在界面下方,会出现提示 a fetch service is working,如下图

 

提示一:如果在这个操作过程中,出现“找不到某某路径”的错误提示,请确定你所有的文件(夹)没有使用中文名称——如果使用中文名称,绝对会出现此错误提示;

提示二:为什么是 ”a fetch service ”呢?问得好,程序支持使用多个AppID,循环调用;

提示三:如何启用XMPP?嗯,在配置界面,Connection标签中,选中enable XMPP即可;

提示四:此时代理已经成功配置,可以启用代理上网了,使用过程中不要关闭客户端界面;

其它相关的一些问题

第一,代理的地址是什么?

呃,刚刚发现,一直到现在还没有提到本地代理地址。其实你应该已经看到了,本地代理127.0.0.1,端口48100

第二,XMPP是什么东东?

我建议善用Google,它是大师傅,随时可以请教。这里简单说一下,它就是一种协议,比如Gtalk就使用XMPP协议。目前Hyk-proxy已经通过了Gtalk/jabber.org/Chatmask.com的验证;

第三,我不想用工具,而想手动用命令行上传服务端代码。

OK,当然没问题,对GAE的SDK环境操作熟练的话,当然可以手动上传,上传目录war,注意上传之前修改WEB-INF/appengine-web.xml中的AppID名称为你自己的;

第四,我不想客户端的GUI界面,也想手动用命令行操作。

欢迎高手使用,在操作前修改etc/hyk-proxy-client.properties中的remoteserver.appid.x

命令行执行bin/start.bat(start.sh)启动 local server, bin/stop.bat(stop.sh)停止;

第五,手动配置是哪个文件?

大部分配置都在hyk-proxy-client.conf中,如果你不想用GUI对话框配置的好,自己手动改吧,具体问题请看官方给出的一些说明,地址在此:http://code.google.com/p/hyk-proxy/

第六,有其它需要注意的吗?

有。第一,启用XMPP模式时,由于XMPP server限制,太频繁发送消息会被server拒绝,可采用配置多个XMPP账户来规避;第二,官方计划启用的EMail模式目前尚未实现,敬请期待!

结束语及其它

有了127.0.0.1:48100,具体怎么使用我就不多说了。注意暂时不要使用客户端bin目录下的admin管理员工具,如果用它配置了用户名和密码的话,可能会导致连接错误。目前官方SVN源码已经解决了这个问题,但是下载包还没有。如果你有兴趣的话,可以直接用SVN获取最新代码;

这段时间一直以来都在寻找、测试、推荐方便易用的web proxy,包括GAE和普通PHP空间的。对如何在浏览器或全局使用代理,以及如何配置代理规则以自动在必要的时候翻墙,还没有写过相关的内容。

有时间的话,我会详细介绍一下各种自动配置代理的方法。

原创文章,转载请注明:
转载自攻防日志
本文链接地址:再次祭出GAE,翻墙利器Hyk-Proxy-Server,该翻就翻