麦鸡(Macji), 记录一些应该记录的东东

MacJiPro

Article list

快速创建基于淘宝开放API(TOP)的Firefox扩展

淘宝开放平台项目(TOP: taobao open platform)是淘宝(中国)软件公司面向3rd app开发者,提供API接口和相关开发环境的平台。

嗯, 这里介绍如何通过基于firefox的javascript去获取淘宝API提供的数据, 其实很简单. 获取数据需要签名和相关API方法, 具体请看API文档.

签名方式为 md5(appsecret + key + value .... key + value)然后转大写字母,其中key,value对是除签名和图片外的所有请求参数按key做的升序排列, value无需编码。

通过服务器端比如php, ruby, python等很容易实现签名方式, 但基于浏览器的javascript貌似望而却步, 但是mozilla提供了javascript的本地扩展, 让你用javascript也能实现更复杂的功能, 比如基于firefox的多线程下载工具. 下面给出简单的签名方式.


//去alisoft申请个app,会给他一个ID和CERT_CODE, 签名的时候需要
API_URL = 'http://sip.alisoft.com/sip/rest/',
APP_NAME = 'baotao', 
APP_ID = '22183',
CERT_CODE = 'cebc9bf0031411de8baffe67f4df8a7b';

  • 首先是md5的实现, 其实javascript也实现md5, 网上有现成的算法, 没仔细研究, 拿来直接用, 发现md5中文后, 有问题, 估计是编码问题, 后来找到mozilla开发者中心的一段javascript实现md5的代码, 对其进行简单封装, 用convertFromUnicode对字符进行转码,再md5.

    
    /**
     * md5
     * @return String
     */
    var md5 = function(str){
    	   var getHexStringFromBinary = function(str){
    	  	    var hexchars = '0123456789abcdef';
    	   	   var hexrep = new Array(str.length * 2);
    	   	   var i;
    	   	   for (i = 0; i < str.length; ++i)
    	  	    {
    			    hexrep[i * 2] = hexchars.charAt((str.charCodeAt(i) >> 4) & 15);
    			    hexrep[i * 2 + 1] = hexchars.charAt(str.charCodeAt(i) & 15);
    	  	    }
    	   	   return hexrep.join('');
    	   }
    	  var hashMd5Hex = function(str){
    	   	   var hash_engine = Components.classes["@mozilla.org/security/hash;1"].createInstance().QueryInterface(Components.interfaces.nsICryptoHash);
    	   	   hash_engine.init(hash_engine.MD5);
    	   	   var charcodes = new Array();
    	   	   for (var i = 0; i < str.length; i++)
    	   	   {
    	   		 charcodes.push(str.charCodeAt(i));
    	   	   }
    	   	   hash_engine.update(charcodes, str.length);
    	   	   return getHexStringFromBinary(hash_engine.finish(false));
    	   }
    	   return hashMd5Hex(convertFromUnicode('UTF-8', str));
    }
  • 升序排序,其实就是把key拿出来排序,再放回去,php.js (via)
    
    /**
     * ksort
     * @return Array
     */
    var ksort = function (array){
    	var tmp_arr = {}, keys = [], key_num = 0, key = '', i = 0;
    
    	for (key in array) {
    		keys[key_num++] = key;
    	}
    	keys = keys.sort();
    	for (i = 0; i < key_num; i++) {
    		key = keys[i];
    		tmp_arr[key] = array[key];
    	}
    	
    	return tmp_arr;
    };
  • urlencode,做转码用,也是来自php.js
    
    /**
     * urlencode
     * @return String
     */
    var urlencode = function(s){
    	var SAFECHARS = "0123456789" +					// Numeric
    					"ABCDEFGHIJKLMNOPQRSTUVWXYZ" +	// Alphabetic
    					"abcdefghijklmnopqrstuvwxyz" +
    					"-_.!~*'()";					// RFC2396 Mark characters
    	var HEX = "0123456789ABCDEF";
    
    	var encoded = "";
    	for (var i = 0; i < s.length; i++ ) {
    		var ch = s.charAt(i);
    		if (ch == " ") {
    			encoded += "+";				// x-www-urlencoded, rather than %20
    		} else if (SAFECHARS.indexOf(ch) != -1) {
    			encoded += ch;
    		} else {
    			var charCode = ch.charCodeAt(0);
    			if (charCode > 255) {
    				alert( "Unicode Character '" 
    						+ ch 
    						+ "' cannot be encoded using standard URL encoding.\n" +
    						  "(URL encoding only supports 8-bit characters.)\n" +
    						  "A space (+) will be substituted." );
    				encoded += "+";
    			} else {
    				encoded += "%";
    				encoded += HEX.charAt((charCode >> 4) & 0xF);
    				encoded += HEX.charAt(charCode & 0xF);
    			}
    		}
    	} // for
    	return encoded;
    };
    
  • 此方法返回url就是签名后的url,在chrome级别里可直接用XMLHttpRequest请求
    
    /**
     * getParameterStr
     * @return String
     */
    var getParameterStr = function(arr){
    	var s = '', c = 'cebc9bf0031411de8baffe67f4df8a7b';
    	arr = ksort(arr);
    	
    	for(var i in arr){
    		if('' != arr[i]){
    			if(i == 'sip_timestamp'){
    				s += i + '=' + urlencode(arr[i]) + '&';
    			}else{
    				s += i + '=' + encodeURIComponent(arr[i]) + '&';
    				
    			}
    			c += i + arr[i];
    		}
    	}
    
    	s += 'sip_sign=' +  md5(c).toUpperCase();
    	return s;
    }
    
  • 最后去初始化相关参数,fields字段请参考api说明
    
    return {
    	init: function(q, pageNo){
    		var arr = parameters;
    		arr['sip_timestamp'] = GetDate.init();	
    		arr['sip_apiname'] = 'taobao.items.get';
    		arr['cid'] = '';
    		arr['q'] = q || 'mac';
    		
    		arr['fields'] = "iid,title,nick,type,cid,pic_path,delist_time,price,post_fee";
    		arr['page_no'] = pageNo || 1;
    		arr['page_size'] = 50;
    
    		return API_URL + '?' + getParameterStr(arr);				
    	}
    }
    

TOP签名还是挺麻烦的,源代码请下载宝淘扩展查看吧。https://addons.mozilla.org/zh-CN/firefox/addon/11309


宝淘, 倒过来淘宝

首先要说明的是,  宝淘是一个Firefox扩展, 一个基于淘宝开放API的简易搜索器, 此扩展完全用javascript去获取数据, 没有用代理, 也就是说淘宝API挂掉, 此扩展才会失效.

界面是抄Mac下的Quicksilver, 那几个字是自己画的, 自己觉得都很漂亮, 哇哈哈.., 不过windows下文字太大了, 有点失真

看预览图吧, 很漂亮滴...

怎么用? 首先下载https://addons.mozilla.org/zh-CN/firefox/addon/11309, 安装后, 右下角会出来一个"淘"的icon, 按ALT+Q呼出, 按TAB或者option+S(Mac), ALT+I(Windows)键入关键字搜索, 然后按方向键左右切换商品, 按方向键"DOWN", 进入商品详情页.

大家反映快捷键不好用, 恩, 用的人多, 这个小玩具下个版本就有自定义快捷键了. 赶快下载试用吧.


又丢弃WP了, 开始Typecho

由于服务器主机到期, 换到另一主机了, 至于现在的主机在哪, 是誰的, 我一无所知. 对我来说, 能用就行....

换主机, 也把WP换成Typecho, 我貌似什么都没做, 空帷 全帮我搞定了. 上周就换了, 一直没时间也懒得弄blog了, 这周休假在家, 想起blog了, 就给它重新写了个皮肤, 设计是抄的(抄自fofronline), 自己稍微改了一下, 代码自己重构了, mac下看起来是比较的漂亮, windows下字体不是很舒服, 也懒得去弄了. 另外不是很了解Typeho, 一些原来blog上的功能都没加, 等了解了再加上去. 另外我厚脸皮的, 把这个皮肤命名为: Enter

如果你有f'irebug之类的工具, 可以看到, 结构中, 没有几个div了, 基本上都换成html5了. 不支持IE浏览器. 去掉css, 看起来也是比较的"完美"了.

因为这不是WP的皮肤, 也没多少人用Typeho, 所以就不提供下载了, 如果你喜欢, 直接看源码和http://labs.macji.com/assets/style.css, 对了, 我已经完全屏蔽IE内核的浏览器了, 也就是说这个皮肤是完全不支持IE内核的浏览器的,  既然你能看到这个页面, 说明你没有用IE. 也不多说了.

恩, 新的系统, 新的皮肤, 新的开始, 每次换blog系统, 我都会这么说, 最近更新blog也很慢, 主要还是太忙了, 忙的累了, 也懒的去更新了. 接下来要克服这个毛病, 还是得坚持更新, 坚持分享.


如何正确处理ajax 302跳转问题

如果我们的web应用有大量的异步请求,而这些异步请求是在web服务器认证的情况下,那当我们请求发生在服务器认证失效下,服务器自动302到登录页面,那我们异步获取的是登录页面的数据。我们看YUI代码,当ajax请求发生301 302属于失败事件。


...
if(httpStatus >= 200 && httpStatus < 300 || httpStatus === 1223){
//
}
...

但事实上,并没有发生失败事件,浏览器会再发一次ajax请求到302的地址,如果还是发生302,一直请求,直到完成请求或者请求跨域失败为止。对于js来说,301 302这种跳转是透明的,无法处理。
测试地址(请用firebug, 打开控制台,查看数据,一目了然)

那到底如何当ajax正确处理302呢,这是浏览器级别的问题,也就是说没有浏览器能正确处理302。对于我们前端来说,正确的验证ajax回来的数据,并给出提示,那也不友好(比如服务器端希望我们去登录页面)。更友好的处理是当服务器端发生302,那ajax就当"错误"处理,也做302跳转。


//success的时候 不是你想要的数据后,做如下验证
if(-1 != data.indexOf('x')){//x为302后页面特定的字符
	var LOGIN_DOMAIN = 'xxx';//302地址
	window.location = LOGIN_DOMAIN;
	return true;
}

//当302跳转后,ajax发生跨域,可以在failure处理,但 ie返回的是o.status 是 0
failure: function(o){
	if(302 == o.status){
		//
	}
}

牛气冲天

已经1点了,牛年到了,鼠年我做了什么,新的一年,我又该回顾点什么呢?

嗯,08年4月,结束了我人生的第一份工作,被前老板称之为美工,我不懂设计,不懂美学。我更喜欢的是敲敲代码,研究点我不明白的东西。正如我08年初所说的,我如愿的进入了UED部门,感谢小马哥带我进入淘宝UED,成为一位web前端开发者,这比美工要好听多了,为了对得起这title,我正努力的学习着。

2008年,工作很忙,但正是忙才能让我有所进步。

2008年,感谢小马,安排有意思的工作给我,当我反馈工作给你时,你总是说这不行,那不行,正是你说的不,才让我想的更多,思考的更多,进步的更多。完美主义的你,让我学到很多很多。但总觉得有点抱歉,每次去你家吃饭,白吃白喝,打麻将还赢你们钱,我在这里表示抱歉啦。

2008年,感谢正淳,你的热心,接触过你的人,都知道你是多么的热心,拜托你的事,准没问题。听到你的声音,就知道你有多么的爱淘宝,爱工作。从最底层看问题,让我也了解到问题的另一面。你说我能教你的,就是那点经验。这话不是一般人能听得到的,感动ing。

2008年,最要感谢我的师傅 圆心,让我重新认识技能上的东东,你的学习方法,你的学习态度,你看问题的方式,做的你徒弟,我学到的太多了,唯一没学到的就是你的体重=.=,我没有在骂人哦,说实在话,谢谢你在这一年中带着我,你不烦耐心的跟我讲解着这个问题那个问题,09年,我会加油的。

2008年,要感谢的人太多了,感谢UED前端组,也感谢我自己。

2009年,该做点什么呢,提高效率。工作为什么很忙,效率是一方面,当然经验是效率的瓶颈。要好好记录工作最花时间的地方,总结原因。希望09年少加班,按时回家,然后做一些自己喜欢做的事。希望借着牛年,让我自己变得牛气冲天。

2009年,87年的我,多多少少也有点年纪了,看着UED进来比我年轻的人,感叹年轻真好,后生可畏。当然我也没有资格说这些话,我还是挺年轻的。嗯,比猥琐男,比学术男,比腔调男要年轻多。好好努力,好好去对得起这个年纪,对的起我的title。

娟娟,你真的太好了,我是一个不会说话的人,很多肉麻的话,我都没说出来。在新年之际,我要在这里好好谢谢你。时间过得真快,一年这么快就过去了,这一年中你从东边跟着我到西边,这些苦,这些累,你从来不说;这一年我们在欢声笑语中,让给我们更懂得了生活是平淡的,但我们让平淡的生活,变得非常的缤纷多彩;在这一年,我加班没时间陪你,你总是很体贴我,我加班回来,你总是会给我烧蛋炒饭,紫菜汤,我累了,你会给我按摩。我有这么好的一个老婆,我骄傲啊。在09年,我要做到逛街不喊累,吃辣不喊辣,吃醋不喊酸。其实还有很多话要说,这些全都是只属于我们俩的。

2009年,结果,结果,结果,让我们的结果牛气冲天。


  1. 1
  2. 2
  3. 3
  4. 4
  5. ...
  6. 7