[2008-07-24 07:49:47] 基于Picasa、PHP、AJAX的图片REST架构的简单实现 完结篇
//NOTOC
一如既往的前情提要:
*[blog:98|基于Picasa、PHP、AJAX的图片REST架构的简单实现(1)]
*[blog:99|基于Picasa、PHP、AJAX的图片REST架构的简单实现(2)]
*[blog:104|基于Picasa、PHP、AJAX的图片REST架构的简单实现(3)]
现在,服务器端的架设终于全部结束了,我们可以向服务器端同一个URL发送不同的Header请求,从而得到不同的反馈,REST简单说来也就是这么一回事。但很遗憾,URL只有一个,而且现在的浏览器并没有智能到可以通过超链接携带Header信息。我们只能通过附加手段达到目的,这个附加手段毫无疑问就是最后一位主角:Ajax。
====Step.3 客户端通过Ajax发送不同的Header请求====
准确的说我们利用的是[http://www.w3.org/TR/XMLHttpRequest/|XMLHttpRequest]对象,来对服务器发送不同的header请求。在W3C的定义中,不仅能够找到GET、POST,XMLHttpRequest支持的header类型一共包括
*GET
*POST
*HEAD
*PUT
*DELETE
*OPTIONS
这些Methods早在1999年就被定义于[http://www.ietf.org/rfc/rfc2616|RFC2616]里,到今天终于有了用武之地,真是可喜可贺。
var client = new XMLHttpRequest();
client.open("GET", "test.txt", true);
client.send();
这就是一个最简单的通过XMLHttpRequest发送请求的例子,同理可以将GET替换为其他Method。如果再加上监听状态变化的readystatechange,以及获得反馈的responseXXX,你会发现Ajax原来就是这么一回事。
这里为了使演示更加简单,使用JQuery的Ajax应用,以下是客户端代码:
$("img").each(function(){
var src = $(this).attr("src");
var aim = $(this);
$.ajax({
type: "GET",
url: src,
dataType : 'json',
success: function(json){
var title= "<p>这是一张名为「" + json.title + "」的相片<br />拍摄于:" + json.date + "<br />你可以访问:" + json.full + "来获得这张照片的全图。</p>";
aim.after(title);
aim.attr("alt",json.title);
}
});
return false;
});
这段代码遍历页面的所有图片,然后对这张图片的URL发送Get请求。发送的请求被我们编写的服务器端接收并取得对应的Json数据并返回,最终在客户端显示出来。
至此,这个最简单的图片REST架构便完成了,或许花这么大功夫最终只显示出一张图片来,还称之为构架,实在是小题大作。但最终能剔除所有冗余信息并实现HTML代码的最简化,我自己是玩的不亦乐乎的。
最后附上[http://cid-01e48df64f8bd957.skydrive.live.com/embedrowdetail.aspx/Source/photorest.7z|全部代码下载],也可以[lab:/photo_rest/|在线查看]。
=====付录:HTTP-Header最高绝技之翻墙术=====
其实在国内有很多AV国的网站上不了,并不是GFW的功劳,而网站为了避免拦截正常的访问,也很少会去封IP段。那么究竟为什么很多XX站不能访问呢,在HTTP-Header中,有一个叫Accept-Language的字段负责描述用户的系统语言,国内的Accept-Language值一般都是zh-cn,zh,AV国的很多网站都是通过识别这个值来区别用户。
那么很简单,更改Accept-Language伪装成AV国用户就可以了。
*Firefox下,地址栏访问about:config,然后搜索intl.accept_languages,将值由zh-cn,zh改为ja即可。
*IE下,工具——Internet选项——语言——将列表里的语言全部删除即可。
恩恩,这也只是一个技术问题,大家回去自行研究吧。
Read More
[2008-06-04 09:05:16] Javasript Date对象的扩展、国际化、总结及其他
一个优秀的程序必须要兼顾I18n和L10N,但Javascript在Date处理这一方面做得很不友好,问题反映在以下几个方面:
#虽然Js也设置了UTC时间函数,但脚本运行时的时区是自动从系统获得的,且无法更改。而在实际应用中,往往需要接受一个非当前系统时区的时间数据进行转换,这时候Js的自作聪明就带来了许多麻烦。
#Js对日期的自动解析和格式化输出根据系统环境、浏览器环境不同,表现也不同,这主要反映在Date.parse和toLocaleString方法上,有兴趣的同学可以自行测试。
为了尽可能简便的改善Js的Date处理能力,这里只对Js的Date对象做了两个扩展
/**
* 获得当前时间的UTC时间戳
* @return {int} unix timestamp
*/
Date.prototype.getTimeUTC = function() {
return this.getTime() + this.getTimezoneOffset() * 60 * 1000;
}
/**
* 将当前操作的时间变更时区(主要用于转换一个其他时区的时间)
*
* @param {int} tzo 原时区 -12~13
* @param {int} tzo 目标时区 -12~13 默认为当前时区
*/
Date.prototype.changeTimezone = function(tzo,tzn) {
tzo = tzo * 60;
tzn = tzn ? tzn * 60 : -this.getTimezoneOffset();
this.setTime(this.getTime() - (tzo - tzn) * 60 * 1000);
}
至此,就可以基于这个扩展过的Js Date对象进行新的开发。
思路很简单,就是把任意格式任意时区的时间先通过changeTimezone方法转到和当前系统同一时区下,然后再对getTimeUTC生成的UTC Unix时间戳进行操作。
比如我要计算 +8 时区下 4 Jun 2008, 16:30时刻 与 +9 时区下的当前时刻相差的时间
//自动解析成unix时间戳
var p = Date.parse('4 Jun 2008, 16:30');
var time_parse = new Date(p);
//转换到要对比的时区
time_parse.changeTimezone(8,9);
var time_now = new Date();
//都转换为UTC进行对比
var der = time_now.getTimeUTC() - time_parse.getTimeUTC();
alert('相差' + parseInt(der / 1000 / 60) + '分钟');
当然有更简单的编码,但在复杂运用中理清思路更加不容易出错。
如果想要实现本Blog左侧栏XX天XX月前这样更人性化的提示,这里可以根据自己的需要做进一步扩展。实现的函数如下
/**
* 表示指定时间与现在的差值
*
* @param {int} t 所要比较的时间 unix timestamp (UTC)
* @param {int} n 作为标准的时间,默认为现在时刻 unix timestamp (UTC)
* @return {string} 对相差时间的表述
*/
Date.prototype.derTime = function(t,n) {
var n = n ? n : this.getTimeUTC();
function ms2min(ms) {
return parseInt(ms / 1000 / 60);
}
var der = ms2min(n - t);
var ba = der > 0 ? '前' : '后';
der = Math.abs(der);
var res = '';
if(der == 0) {
res = '刚刚';
}
else if(0 < der && der < 60) {
res = der + '分钟' + ba;
}
else if(60 <= der && der < 24 * 60) {
var min = der % 60 == 0 ? '' : String(der % 60) + '分钟';
res = String(parseInt(der / 60)) + '小时' + min + ba;
}
else if(der >= 24 * 60 && der < 24 * 60 * 31) {
res = String(parseInt(der / 60 / 24)) + '天' + ba;
}
else if(der >= 24 * 60 * 31 && der < 24* 60 * 365) {
res = String(parseInt(der / 60 / 24 / 31)) + '个月' + ba;
}
else if(der > 24 * 60 * 365) {
res = String(parseInt(der / 60 / 24 / 365)) + '年' + ba;
}
return res;
}
/**
* 解析一个时间字段与当前时间的差
* @param {string} i
* @param {int} 时区 -12~13
*/
function time_der(i,tz) {
var p = Date.parse(i);
if(!p) {
return i;
}
var time_parse = new Date(p);
if(tz != undefined) {
time_parse.changeTimezone(tz);
}
var time_now = new Date();
return time_now.derTime(time_parse.getTimeUTC());
}
Read More
[2008-05-30 08:49:56] 轻量级的Accordion With JQuery
Jquery的UI中是有Accordion的,200余行代码配合themes带来的负担,让使用前不可不慎重考虑。
仔细分析一下Accordion的动作其实很简单,顺序排列的N个元素,页面载入时只显示其中一个,点击某个元素时,展开当前元素并隐蔽其他。
那么配合JQuery强大的选择器,完全可以用几行代码打造自己的轻量级Accordion。
以本Blog的左边侧栏为例:
//页面载入时隐蔽除第一个元素外所有元素
$("#accordion > li > div + *:not(:first)").hide();
//对所有元素的标题绑定点击动作
$('#accordion > li > div').click(function(){
$(this).parent().parent().each(function(){
//隐蔽所有元素
$("> li > div + *",this).slideUp();
});
//展开当前点击的元素
$("+ *",this).slideDown();
});
总共不过7行,当然选择对象部分需要根据自己的情况灵活指定。
ASUS Eee,华硕又见华硕,难道我是ASUS控么- -|||
Read More
