易栈网-膘叔

浏览模式: 标准 | 列表 | 图文

kenai.com即将关闭

说起kenai,那其实是要说很多很多东西的,比如说,netbeans整合了它,比如说他现在属于oracle了,比如说他是一个开源代码库,类似于Sf.net等。

但是,今天上午收到一封邮件说,kenai.com即将关闭了,不再为开源代码库提供服务了。

邮件主题很简单:The Closure of Project Kenai。

邮件内容也很简单:

It's with a sad heart that we have to announce that the Kenai.com domain will be shutdown as part of the consolidation of project hosting sites now that Sun is a wholly owned subsidiary of Oracle.

Project Kenai has always existed as two different things: Kenai the infrastructure, and Kenai the website (Kenai.com). While it has come time to close the domain of Kenai.com, the infrastructure (which is already used under NetBeans.org) will live on to support other domains in the future.
然后就是告诉我,该准备一下往其他源代码服务器上迁移,并且提示我可以用subversion等工具把代码拷贝出来。否则。。。唉。

可怜我的sbphp就是放在kenai上面的现在,是全完了。不过反正我也准备重写了,倒也无所谓,只是又少了一个源代码迁入的地方。看来netbeans也需要更新了。期待再次整合一个网站。

jQuery操作select

jQuery操作select

jQuery这个框架方便了我们对于HTML元素的操作,本来以为自己对于Select操作也算是熟悉了,但上午在测试的时候才发现自己了解的还真不多。

看了一下jQuery的一些方法后,理出了一些常用的方法,列在下面:

//获取第一个option的值
$('#test option:first').val();
//最后一个option的值
$('#test option:last').val();
//获取第二个option的值
$('#test option:eq(1)').val();
//获取选中的值
$('#test').val();
$('#test option:selected').val();
//设置值为2的option为选中状态
$('#test').attr('value','2');
//设置第一个option为选中
$('#test option:last').attr('selected','selected');
$("#test").attr('value' , $('#test option:last').val());
$("#test").attr('value' , $('#test option').eq($('#test option').length - 1).val());
//获取select的长度
$('#test option').length;
//添加一个option
$("#test").append("<option value='9'>ff</option>");
$("<option value='9'>ff</option>").appendTo("#test");
//添除选中项
$('#test option:selected').remove();
//指定项选中
$('#test option:first').remove();
//指定值被删除
$('#test option').each(function(){
if( $(this).val() == '5'){
$(this).remove();
}
});
$('#test option[value=5]').remove();

//获取第一个Group的标签
$('#test optgroup:eq(0)').attr('label');
//获取第二group下面第一个option的值
$('#test optgroup:eq(1) :option:eq(0)').val();

想来应该够用了吧?呵呵

sexy button

sexy button

对于非美工来说,做一个漂亮的button是件很痛苦的事情。当然,对于一位美工,即使是做个好一点的button,想来也不会太简单。你可以看看这里。。

或许你认为这样的BUTTON很简单:

12fc10a193fc6bf5780adc5d16b7d728

这样自定义图标的呢?

f7bd8a59698ea5fa0cb11f4f37901012

那么,这样的呢?

2a58d4463baa0310c963655e726ffe73

如果上面都简单,那么还有这么多的样式呢,你认为怎么样?

ba385d749fa5d28d859ed9fe4f3fc1bd

觉得不错的话。到这里看看:http://sexybuttons.googlecode.com/svn/tags/1.0/index.html

如果觉得真不错,那么到:http://code.google.com/p/sexybuttons/下载吧。一些小图片加上CSS,不需要再利用js做圆角了。看看作者怎么说?

Sexy Buttons is a HTML/CSS-based framework for creating beautiful web site buttons. These stylish, attention getting buttons can be used for calls to action wherever user interaction is desired. Compare Sexy Buttons with the standard browser buttons:

The framework is focused on being simple yet flexible and strives to be as easy to implement as possible.
Button Features

* The underlying HTML can use either <button> or <a> elements.
* They are dynamic and shrink/expand to fit their text labels.
* There are three states: normal, hover, and active.
* The labels can include icons. Use one of the 1000+ included Silk icons or use your own. Icons are specified via HTML class attribute.
* They use the sliding doors CSS technique for increased performance.
* They support different skins by simply changing an HTML class attribute.
* A layered Photoshop template is provided to assist in creating new skins.
* Easy to implement.
* No Javascript required.

这些可是支持所有浏览器的哦

开心网转贴:残酷的现实

开心网转贴:残酷的现实

  张二狗是偶的同学。一直以来,偶们都是被人拿来作为对比的两个极端,偶曾经是他的梦魇,现在他却是偶的梦魇。现将偶和他的人生历程列出来,再一次深刻感受风水轮流转这一永恒真理。

1、小学入学第一天,偶对老师说会背301首唐诗做100以内加减法,口齿清晰条理清楚,老师对偶眉开眼笑。  
小学入学第一天,张二狗对老师的提问一问摇头三不知,神情呆滞语无伦次,老师对他暗暗皱眉。

2、小学二年级,偶考试次次第一,终于在一次满分后肩膀上多了三条杠杠。  
小学二年级,张二狗和人打架有赢有输,终于在一次大败后脸上多了三条疤疤

3、小学三年级,期末考试偶再次拿到语文数学两门功课双一百,老爸被老师请到家长会上介绍家庭教育经验。  
小学三年级,期末考试张二狗再次拿到语文数学两门功课总分三十,老爸被老师请进办公室聆听家庭教育经验。

4、小学四年级,领导前来视察我校,偶作为少先队代表上台发言,被大家称为主席台上的模范学生。  
小学四年级,校长宣布从严治校,张二狗作为闯祸精代表上台检讨,被大家说是站壁角的形象大使。

5、小学五年级,偶的作文《一个难忘的晚上》在某次大赛中获奖,老师陪偶到省城领奖并游玩了一天。  
小学五年级,张二狗在一个难忘的晚上爬墙进入某个工厂搬运废铜,门卫陪他到派出所领奖并休养了一天。

6、升初中了,听说初中的几个班主任为抢偶到自己班上而争得面红耳赤。  
升初中了,听说初中的几个班主任为把张二狗踢到别人班上闹得不可开交。

7、初一时,偶爸在酒店设宴庆功,为偶在中学生奥数中获奖请别人一起高兴。
初一时,张二狗爸在酒店设宴赔罪,为张二狗闯的祸请别人不要追究

8、初二时,偶光荣地加入了学校里的团组织  
初二时,张二狗光荣地加入了学校里的痞子帮

9、初三时,班上的班花给偶写情书,情书还没到偶手里就被班主任发现没收,班主任警告班花:不得妨碍偶考重点高中  
初三时,张二狗给班上的胖妞如花递纸条,如花转身把纸条扔进垃圾桶,还告诫张二狗:不要妨碍她混初中文凭

10、初中毕业了,偶理所当然地进入了重点高中  
初中毕业了,张二狗顺理成章地进入社会深造

11、毕业那天,偶们初中的门卫李大爷指着偶教育大孙子:一定要像偶这样好好学习天天向上,将来才能做个受尊敬的人  
毕业那天,偶们初中的门卫李大爷指着张二狗教育大孙子:千万不要像他这样惹是生非门门红灯,将来一定是个受鄙视的人

12、高中三年,偶做过班长团支书学生会主席,获得了一个又一个荣誉、拿到了一笔又一笔的奖学金  
社会三年,张二狗做过混混推销员包工头,积累了一条又一条的人脉,攒下了一笔又一笔资金

13、那个黑色七月,偶如愿考上省城的大学  
那个火热七月,张二狗如愿在省城注册公司

14、大学里,偶在学海遨游  
创业中,张二狗在商海搏击

15、毕业那年,优秀毕业生偶进入人才市场找工作,处处碰壁后不得不把薪金要求降?
创业四年,民营企业家张二狗进入人才市场找员工,广受追捧后不得不把学历门槛提高到硕士起点,很轻松招揽一群高学历高层次的人才,感受了一夜之间从丑小鸭到白天鹅的荣耀

16、偶的破永久跑遍全省城,孤身一人凄凄凉凉四处寻找租住的房子  
张二狗的保时捷跑遍全省城,市长区长作陪四处寻找建二狗大厦和工业园区的地块

17、当红女明星来省城开演唱会,偶买不到演唱票,便在体育馆外和女朋友傻站半宿,还被女朋友骂:买不到票,真没用  
当红女明星来省城开演唱会,演唱结束后张二狗亲自开着奔驰把明星接到别墅共度良宵,还被女明星夸:偌大家业,你真行

18、偶手头紧张,也想学张二狗白手起家自主创业,从小商品市场批发了一大堆东东搞兼职做起了推销,几星期内亏了一大笔,暗自感慨:做生意原来这么难  
张二狗闲来无事,也想进大学校门学习深造增加内涵,请教授吃饭泡校里的美眉就是没认真上课,几年内拿到了MBA学位,暗自感慨:读书原来这么简单

19、七夕节,别人介绍的恐龙女朋友嫌弃偶没房没车没出息,和偶吹灯拔蜡分道扬镳  
七夕节,大学里的校花因为张二狗家大业大前程大,向他眉目传情投怀送抱

20、家门口,偶哀求俗气的土包子房东缓交房费时唯唯诺诺支支吾吾,净给大学生丢脸  
电视上,张二狗对着漂亮的财经频道女主持人大谈企业文化?  

21、房价飞涨,偶忽然发现在省城有一套房子只能是一个梦想,老爹老妈来省城看过偶的租住房,回家后伤心不已  
房价飞涨,张二狗把一套又一套的房子赠给各类美女,一小美女的老爹老妈来省城看过二狗赠的复式景观房,回家后得意不已

22、春节偶回家,没人理睬,路过当年就读的初中,听说里面在办校庆,想去看看却被拒之门外,门卫李大爷指着偶教育小孙子:不要学习这个人,读了这么多年书还是一穷二白,连自己都养不活  
春节张二狗回家,县长接驾,还参加当年就读的初中特意举办的校庆,张董在校庆上砸下巨额赞助,门卫李大爷指着张董教育小孙子:你要像主席台上的这个人学习,白手起家富甲一方,连亲戚都沾光

23、十几年前,老师感叹,要是所有学生都像偶一样该有多好  
十几年后,老师感叹,要是所有学生都想张二狗一样该有多好

可怜的小家伙

可怜的小家伙

从元旦开始,小家伙就感冒不断,当然,鼻涕也是不停的在流
上次我说过发了风疹块,好象是好了。
前两天,突然又开始感冒,流鼻涕,而且今天身上又开始发小点点。真的不知道是水痘还是别的什么。
皮肤过敏也不能这样吧?难道夏天生的小孩抵抗能力这么差?
唉。希望好起来吧,今天鼻涕已经流了整一天了。看着我非常不开心,不知道他的身体什么时候能够恢复。
算起来,有一个月了呢。
唉。祈祷一下吧。

一小段音乐:我没有钱,我不要脸

一小段音乐:我没有钱,我不要脸

从amr转为mp3并截取过的。。

AMR是手机音乐,下载了:total video converter,先用它把amr转换成MP3

然后用goldwave把Mp3进行了编辑。最后就是这么一小段了。。

因为杂音过多。所以仅保留这段经典的

注:

由于有很多朋友強烈抗議,因此,把自動播放去掉了。請主動點擊。謝謝

一旦點擊就自動循環啦,請仔細聽,歌詞是:我沒有錢,我不要臉。。。

ThinkPHP经常会遗忘的事

ThinkPHP经常会遗忘的事

使用THinkPHP框架开发程序,经常容易遗忘的事是什么呢?
1、app runtime没有及时更新
2、datamodel 缓存在更改表结构后没有刷新
3、数据缓存设定的时间太长。而在更改数据后没有主动刷新

4、模版缓存中的 include file 一般不会强制刷新。。

以上是开发注意事情,如果你发现改了一些设置或者其他什么后,死活不正常,请先检查以上四样。

孟宪会之AJAX(XMLHttpRequest)进行跨域请求方法详解

孟宪会之AJAX(XMLHttpRequest)进行跨域请求方法详解

孟宪会友情提醒:注意:以下代码请在Firefox 3.5、Chrome 3.0、Safari 4之后的版本中进行测试。IE8的实现方法与其他浏览不同。

跨域请求,顾名思义,就是一个站点中的资源去访问另外一个不同域名站点上的资源。这种情况很常见,比如说通过 style 标签加载外部样式表文件、通过 img 标签加载外部图片、通过 script 标签加载外部脚本文件、通过 Webfont 加载字体文件等等。默认情况下,脚本访问文档属性等数据采用的是同源策略(Same origin policy)。

那么,什么是同源策略呢?如果两个页面的协议、域名和端口是完全相同的,那么它们就是同源的。同源策略是为了防止从一个地址加载的文档或脚本访问或者设置 从另外一个地址加载的文档的属性。如果两个页面的主域名相同,则还可以通过设置 document.domain 属性将它们认为是同源的。

随着 Web2.0 和 SNS 的兴起,Web 应用对跨域访问的需求也越来越多,但是,在脚本中进行跨域请求是受安全性限制的,Web 开发人员迫切需要提供一种更安全、方便的跨域请求方式来融合(Mashup)自己的 Web 应用。这样做的一个好处就是可以将请求分摊到不同的服务器,减轻单个服务器压力以提高响应速度;另外一个好处是可以将不同的业务逻辑分布到不同的服务器上 以降低负载。

值得庆幸的是,跨域请求的标准已经出台,主流浏览器也已经实现了这一标准。W3C 工作组中的 Web Applications Working Group(Web 应用工作组)发布了一个 Cross-Origin Resource Sharing(跨域资源共享,该规范地址:http://www.w3.org/TR/access-control/和http: //dev.w3.org/2006/waf/access-control/) 推荐规范来解决跨域请求的问题。该规范提供了一种更安全的跨域数据交换方法。具体规范的介绍可以访问上面提供的网站地址。值得注意的是:该规范只能应用在 类似 XMLHttprequest 这样的 API 容器内。IE8、Firefox 3.5 及其以后的版本、Chrome浏览器、Safari 4 等已经实现了 Cross-Origin Resource Sharing 规范,已经可以进行跨域请求了。

Cross-Origin Resource Sharing 的工作方式是通过添加 HTTP 头的方法来判断哪些资源允许 Web 浏览器访问该域名下的信息。然而,对于那些 HTTP 请求导致用户数据产生副作用的请求方法(特别是对于除了GET、某些 MIME 类型的 POST 之外的 HTTP方法),该规范要求浏览器对请求进行“预先验”,通过发送 HTTP 的 OPTIONS 请求头询问服务器有哪些支持的方法,在征得服务器的同意后,再使用实际的 HTTP 请求方法发送实际的请求。服务器也可以通知客户端是否需要将验证信息(如 Cookie 和 HTTP Authentication 数据)随同请求一起发送。

下面我们就采用实际的例子说明 Cross-Origin Resource Sharing 是如何工作的。

1,简单请求

什么样的请求算是简单请求呢?简单请求必须满足下面2点:
a,只使用 GET、POST 进行的请求,这里的POST只包括发送给服务器的数据类型(Content-Type)必须是 application/x-www-form-urlencoded、multipart/form-data 或者 text/plain中一个。
b,HTTP 请求没有设置自定义的请求头,如我们常用的 X-JSON。

先使用下面的代码进行测试:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>孟宪会之AJAX跨域请求测试</title>
</head>
<body>
<input type='button' value='开始测试' onclick='crossDomainRequest()' />
<div id="content"></div>
<mce:script type="text/javascript"><!--
var xhr = new XMLHttpRequest();
var url = 'http://dotnet.aspx.cc/SimpleCrossSiteRequests.aspx';
function crossDomainRequest() {
document.getElementById("content").innerHTML = "开始……";
if (xhr) {
xhr.open('GET', url, true);
xhr.onreadystatechange = handler;
xhr.send();
} else {
document.getElementById("content").innerHTML = "不能创建 XMLHttpRequest";
}
}
function handler(evtXHR) {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
var response = xhr.responseText;
document.getElementById("content").innerHTML = "结果:" + response;
} else {
document.getElementById("content").innerHTML = "不允许跨域请求。";
}
}
else {
document.getElementById("content").innerHTML += "<br/>执行状态 readyState:" + xhr.readyState;
}
}
// --></mce:script>
</body>
</html>

然后,在服务器创建 CrossDomainRequest.aspx 的内容如下:

<%@ Page Language="C#" %>
<mce:script runat="server"><!--
protected void Page_Load(object sender, EventArgs e)
{
Response.AddHeader("Access-Control-Allow-Origin", "http://www.meng_xian_hui.com:801");
Response.Write("孟宪会向各位朋友发来贺电:你的第一个跨域测试成功啦!!!");
}
// --></mce:script>

点击 “开始测试” 按钮,发送的请求和返回的响应信息如下:

GET /SimpleCrossSiteRequests.aspx HTTP/1.1
Host: dotnet.aspx.cc
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.2; zh-CN; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 (.NET CLR 3.5.30729)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-cn,zh;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: GB2312,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Referer: http://www.meng_xian_hui.com:801/CrossDomainAjax/SimpleCrossSiteRequests.html
Origin: http://www.meng_xian_hui.com:801
HTTP/1.x 200 OK
Date: Sun, 10 Jan 2010 13:52:00 GMT
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
X-AspNet-Version: 2.0.50727
Access-Control-Allow-Origin: http://www.meng_xian_hui.com:801
Set-Cookie: ASP.NET_SessionId=wk5v5nrs5wbfi4rmpjy2jujb; path=/; HttpOnly
Cache-Control: private
Content-Type: text/html; charset=utf-8
Content-Length: 84

需要特别注意的是:在请求信息中,浏览器使用 Origin 这个 HTTP 头来标识该请求来自于 http://www.meng_xian_hui.com:801;在返回的响应信息中,使用 Access-Control-Allow-Origin 头来控制哪些域名的脚本可以访问该资源。如果设置 Access-Control-Allow-Origin:*,则允许所有域名的脚本访问该资源。如果有多个,则只需要使用逗号分隔开即可。

注意:在服务器端,Access-Control-Allow-Origin 响应头 http://www.meng_xian_hui.com:801 中的端口信息不能省略。

有人可能会想:自己发送请求头会如何呢?比如 xhr.setRequestHeader("Origin","http://www.meng_xian_hui.com:801"); 实践证明,自己设置 Origin 头是不行的。

是不是现在就可以采用 XMLHttpRequest 来请求任意一个网站的数据呢?还是不行的。允许哪些域名可以访问,还需要服务器来设置 Access-Control-Allow-Origin 头来进行授权,具体的代码是:

Response.AddHeader("Access-Control-Allow-Origin", "http://www.meng_xian_hui.com:801");

这行代码就告诉浏览器,只有来自 http://www.meng_xian_hui.com:801 源下的脚本才可以进行访问。

好了,上面我们就完成了一个简单的跨域请求,怎么样?感觉还是不错的吧。下面我们进行一个“预检”请求。

2,预检请求

预检请求首先需要向另外一个域名的资源发送一个 HTTP OPTIONS 请求头,其目的就是为了判断实际发送的请求是否是安全的。下面的2种情况需要进行预检:
a,不是上面的简单请求,比如使用Content-Type 为 application/xml 或 text/xml 的 POST 请求
b,在请求中设置自定义头,比如 X-JSON、X-MENGXIANHUI 等

注意:在 iis 里进行测试,必须在“应用程序扩展”里面配置 .aspx 扩展的动作允许 OPTIONS。

下面我们举一个预检的请求:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>孟宪会之AJAX跨域请求测试</title>
</head>
<body>
<input type='button' value='开始测试' onclick='crossDomainRequest()' />
<div id="content"></div>
<mce:script type="text/javascript"><!--
var xhr = new XMLHttpRequest();
var url = 'http://dotnet.aspx.cc/PreflightedRequests.aspx';
function crossDomainRequest() {
document.getElementById("content").innerHTML = "开始进行请求……";
if (xhr) {
var xml = "<root>测试</root>";
xhr.open('POST', url, true);
xhr.setRequestHeader("POWERED-BY-MENGXIANHUI", "Approve");
xhr.setRequestHeader("Content-Type", "application/xml");
xhr.onreadystatechange = handler;
xhr.send(xml);
} else {
document.getElementById("content").innerHTML = "不能创建 XMLHttpRequest。";
}
}
function handler(evtXHR) {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
var response = xhr.responseText;
document.getElementById("content").innerHTML = "结果:" + response;
} else {
document.getElementById("content").innerHTML = "不能进行跨越访问。";
}
}
else {
document.getElementById("content").innerHTML += "<br/>执行状态 readyState:" + xhr.readyState;
}
}
// --></mce:script>
</body>
</html>

上面的例子我们发送 xml 格式的数据,并且,发送一个非标准的HTTP头 POWERED-BY-MENGXIANHUI 来说明服务器端该如何设置响应头的。

在服务器端,PreflightedRequests.aspx 的内容如下:

<%@ Page Language="C#" %>
<mce:script runat="server"><!--
protected void Page_Load(object sender, EventArgs e)
{
if (Request.HttpMethod.Equals("GET"))
{
Response.Write("这个页面是用来测试跨域 POST 请求的,直接浏览意义不大。");
}
else if (Request.HttpMethod.Equals("OPTIONS"))
{
//通知客户端允许预检请求。并设置缓存时间
Response.ClearContent();
Response.AddHeader("Access-Control-Allow-Origin", "http://www.meng_xian_hui.com:801");
Response.AddHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
Response.AddHeader("Access-Control-Allow-Headers", "POWERED-BY-MENGXIANHUI");
Response.AddHeader("Access-Control-Max-Age", "30");
//此过程无需返回数据
Response.End();
}
else if (Request.HttpMethod.Equals("POST"))
{
if (Request.Headers["Origin"].Equals("http://www.meng_xian_hui.com:801"))
{
System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
doc.Load(Request.InputStream);
Response.AddHeader("Access-Control-Allow-Origin", "http://www.meng_xian_hui.com:801");
Response.Write("您提交的数据是:<br/><br/>" + Server.HtmlEncode(doc.OuterXml));
}
else
{
Response.Write("不允许你的网站请求。");
}
}
}
// --></mce:script>

点击“开始测试”按钮,将会执行下面的一系列请求。

OPTIONS /PreflightedRequests.aspx HTTP/1.1
Host: dotnet.aspx.cc
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.2; zh-CN; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 (.NET CLR 3.5.30729)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-cn,zh;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: GB2312,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Origin: http://www.meng_xian_hui.com:801
Access-Control-Request-Method: POST
Access-Control-Request-Headers: powered-by-mengxianhui
HTTP/1.x 200 OK
Date: Sun, 10 Jan 2010 14:00:34 GMT
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
X-AspNet-Version: 2.0.50727
Access-Control-Allow-Origin: http://www.meng_xian_hui.com:801
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers: POWERED-BY-MENGXIANHUI
Access-Control-Max-Age: 30
Set-Cookie: ASP.NET_SessionId=5npqri55dl1k1zvij1tlw3re; path=/; HttpOnly
Cache-Control: private
Content-Length: 0
POST /PreflightedRequests.aspx HTTP/1.1
Host: dotnet.aspx.cc
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.2; zh-CN; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 (.NET CLR 3.5.30729)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-cn,zh;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: GB2312,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
POWERED-BY-MENGXIANHUI: Approve
Content-Type: application/xml; charset=UTF-8
Referer: http://www.meng_xian_hui.com:801/CrossDomainAjax/PreflightedRequests.html
Content-Length: 19
Origin: http://www.meng_xian_hui.com:801
Pragma: no-cache
Cache-Control: no-cache
<root>测试</root>
HTTP/1.x 200 OK
Date: Sun, 10 Jan 2010 14:00:34 GMT
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
X-AspNet-Version: 2.0.50727
Access-Control-Allow-Origin: http://www.meng_xian_hui.com:801
Set-Cookie: ASP.NET_SessionId=byvose45zmtbqy45d2a1jf2i; path=/; HttpOnly
Cache-Control: private
Content-Type: text/html; charset=utf-8
Content-Length: 65

以上的代码反映了预检请求的执行过程:首先发送 OPTIONS 请求头,用来向服务器咨询服务器的更多信息,以便为后续的真实请求做准备。比如是否支持 POST 方法等。值得注意的是:

浏览器还发送 Access-Control-Request-Method: POST 和 Access-Control-Request-Headers: powered-by-mengxianhui 请求头。

注意:以上过程是第一次请求的时候的过程,如果在 30 秒内重复点击按钮,你可以看不到 OPTIONS 这一过程。则执行过程是这样的:

POST /PreflightedRequests.aspx HTTP/1.1
Host: dotnet.aspx.cc
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.2; zh-CN; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 (.NET CLR 3.5.30729)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-cn,zh;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: GB2312,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
POWERED-BY-MENGXIANHUI: Approve
Content-Type: application/xml; charset=UTF-8
Referer: http://www.meng_xian_hui.com:801/CrossDomainAjax/PreflightedRequests.html
Content-Length: 19
Origin: http://www.meng_xian_hui.com:801
Pragma: no-cache
Cache-Control: no-cache
<root>测试</root>
HTTP/1.x 200 OK
Date: Sun, 10 Jan 2010 14:06:32 GMT
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
X-AspNet-Version: 2.0.50727
Access-Control-Allow-Origin: http://www.meng_xian_hui.com:801
Set-Cookie: ASP.NET_SessionId=qs1c4urxywdbdx55u04pvual; path=/; HttpOnly
Cache-Control: private
Content-Type: text/html; charset=utf-8
Content-Length: 65

为什么会这样?细心的童鞋可能注意到了,在服务器端有一行代码 Response.AddHeader("Access-Control-Max-Age", "30"); 它是用来设置预检的有效时间的,单位是秒。这一点要特别注意。

3,带验证信息的请求

身份验证是Web开发中经常遇到的问题,在跨域请求中,默认情况下是不发送验证信息的。要想发送验证信息,需要进行withCredentials 属性,下面就是一个简单请求的例子:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>孟宪会之AJAX跨域请求测试</title>
</head>
<body>
<input type='button' value='开始测试' onclick='crossDomainRequest()' />
<div id="content"></div>
<mce:script type="text/javascript"><!--
var xhr = new XMLHttpRequest();
var url = 'http://dotnet.aspx.cc/RequestsWithCredentials.aspx';
function crossDomainRequest() {
document.getElementById("content").innerHTML = "开始进行请求……";
if (xhr) {
xhr.open('GET', url, true);
xhr.onreadystatechange = handler;
xhr.withCredentials = "true";
xhr.send();
} else {
document.getElementById("content").innerHTML = "不能创建 XMLHttpRequest。";
}
}
function handler(evtXHR) {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
var response = xhr.responseText;
document.getElementById("content").innerHTML = "结果:" + response;
} else {
document.getElementById("content").innerHTML += "<br/>执行状态 status:" + xhr.status;
}
}
else {
document.getElementById("content").innerHTML += "<br/>执行状态 readyState:" + xhr.readyState;
}
}
// --></mce:script>
</body>
</html>

点击“开始测试”,我们可以检测到下面的请求执行过程:

GET /RequestsWithCredentials.aspx HTTP/1.1
Host: dotnet.aspx.cc
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.2; zh-CN; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 (.NET CLR 3.5.30729)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-cn,zh;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: GB2312,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Referer: http://www.meng_xian_hui.com:801/CrossDomainAjax/RequestsWithCredentials.html
Origin: http://www.meng_xian_hui.com:801
HTTP/1.x 200 OK
Date: Sun, 10 Jan 2010 14:12:26 GMT
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
X-AspNet-Version: 2.0.50727
Access-Control-Allow-Origin: http://www.meng_xian_hui.com:801
Access-Control-Allow-Credentials: true
Set-Cookie: ASP.NET_SessionId=fn2zf0zq1cuwgf45fm5fw145; path=/; HttpOnly
Set-Cookie: visit=1; expires=Sun, 10-Jan-2010 14:12:56 GMT; path=/
Cache-Control: no-cache
Pragma: no-cache
Expires: -1
Content-Type: text/html; charset=utf-8
Content-Length: 1

从上面的响应中可以看出,Cookie 是会随请求一起发送的。如果我们多次点击测试按钮,则可以看到请求和响应的结果是这样的:

GET /RequestsWithCredentials.aspx HTTP/1.1
Host: dotnet.aspx.cc
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.2; zh-CN; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 (.NET CLR 3.5.30729)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-cn,zh;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: GB2312,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Referer: http://www.meng_xian_hui.com:801/CrossDomainAjax/RequestsWithCredentials.html
Origin: http://www.meng_xian_hui.com:801
Cookie: ASP.NET_SessionId=fn2zf0zq1cuwgf45fm5fw145; visit=2
HTTP/1.x 200 OK
Date: Sun, 10 Jan 2010 14:13:58 GMT
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
X-AspNet-Version: 2.0.50727
Access-Control-Allow-Origin: http://www.meng_xian_hui.com:801
Access-Control-Allow-Credentials: true
Set-Cookie: visit=3; expires=Sun, 10-Jan-2010 14:14:28 GMT; path=/
Cache-Control: no-cache
Pragma: no-cache
Expires: -1
Content-Type: text/html; charset=utf-8
Content-Length: 1

注意 Cookie: ASP.NET_SessionId=fn2zf0zq1cuwgf45fm5fw145; visit=2 这一行,访问计数器已经被一起发送到服务器。

4,IE8 中的实现方法

IE8已经开始支持跨域访问资源了,但是,IE8提供的功能还比较简单,可以进行简单的请求,下面是一个使用的例子:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>孟宪会之AJAX跨域请求测试</title>
</head>
<body>
<input type='button' value='开始测试' onclick='crossDomainRequest()' />
<div id="content"></div>
<mce:script type="text/javascript"><!--
var xhr = new XDomainRequest();
var url = 'http://dotnet.aspx.cc/SimpleCrossSiteRequests.aspx';
function crossDomainRequest() {
document.getElementById("content").innerHTML = "开始……";
if (xhr) {
xhr.open('GET', url);
xhr.onload = handler;
xhr.send();
} else {
document.getElementById("content").innerHTML = "不能创建 XDomainRequest";
}
}
function handler(evtXHR) {
document.getElementById("content").innerHTML = "结果:" + xhr.responseText;
}
// --></mce:script>
</body>
</html>

另外,IE8的实现方法与其他浏览器不同。更多内容请参考 XDomainRequest 对象,地址是:
http://msdn.microsoft.com/zh-cn/library/cc288060(VS.85).aspx

最后,愿意测试的朋友可以访问这个 http://dotnet.aspx.cc/SimpleCrossSiteRequests.aspx 地址进行“简单请求”的测试,本页面允许任何地址进行跨域访问。(不好意思,个人网站可能被河蟹了)

----EOF---

很长的文章,我把三篇并为一篇了。。如果嫌长,可以去这里查看 :

AJAX(XMLHttpRequest)进行跨域请求方法详解(一)

AJAX(XMLHttpRequest)进行跨域请求方法详解(二)

AJAX(XMLHttpRequest)进行跨域请求方法详解(三)

合理使用google reader

google reader恐怕很多人都在用吧。当然在国内也有很多人使用有道的RSS订阅,鲜果的RSS订阅。
不过,我仍然是说的google reader,在我的博客里以前也介绍过。

今天我说的合理使用Google reader,是指另类的用法。
一些技术型 的博客,往往都是在国外,而正常的时候,我们好象都无法访问,怎么办?只能借着偶尔翻墙的时机,订阅那些博客的RSS源。如果你用的是国内的RSS订阅,那么也很有可能是无法订阅的。所以,GoogleReader就派用场了。
再深再远,他都能够帮你订阅回来,只是。。。无法回复而己

借着这个功能,我订阅了几个写mysql proxy的作者的博客。
当然更重要的是,我订阅了twitter上的两位:孙燕姿和萧亚轩。。

所以,懂的喽。。。什么非死不可啦,推特啦,博客班点啦。哈哈。。。都可以尝试订阅你所关注的对象,除了这个嘛。。。。你当然仍然不能回复 。除非你为google reader推插件。。。
如果你用firefox写个插件,或许也能够回复哦?

Ways to debug your jQuery or JavaScript codes

Ways to debug your jQuery or JavaScript codes

Debugging your client code is rather a normal procedures for any web developers. Everyone will shout Firebug! yeah, me too. But Firebug is great for syntax detection but how about logic problem? In this article i will share with you some of the ways i used to debug my JavaScript or jQuery codes when I’m developing my web application. I will also share with you a trick that i used on my code to alert me that a bug occurs in a particular script since i don’t get many helpful users nowadays.

Alert Them Out

The most simple and basic way of debugging is by using JavaScript alert function. This is old but is quite useful sometimes. Especially when you do not want to remember other debugging methods. It’s pretty simple, alert the message you want to see. If the alert doesn’t appear, this means that the error is before the alert statement. I usually do this when I’m debugging IE although there are tools available for IE.

alert("The Bug Is Somewhere Before ME!");

Log them up

Well, if you are using WebKit browsers for your development (FireFox, Chrome, Safari) you may want to try this.

if (window.console)
window.console.log("The Bug is killing me");

What this does is to log the string ‘The Bug is killing me’ into the console such as Firebug. It’s always better than using alert and see this infinity loop that keep popping out until you are force to shut down your browser!

Log them with jQuery

The above two methods work both in jQuery and JavaScript. But this only function well in jQuery. This is definitely not something i came up with but its from Dominic Mitchell

jQuery.fn.log = function (msg) {
console.log("%s: %o", msg, this);
return this;
};

The above creates a function, ‘log’. This function will do exactly similar to the one above but the differences is that it format the string a little bit before displaying out to the console. This is good for debugging your long chaining with jQuery. Although the previous method also can be used to debug chaining but it will required an additional line instead of including it into the chaining process. So you can debug this way,

$(root).find('li.source > input:checkbox').log("sources to uncheck").removeAttr("checked");

Try and catch

In JavaScript, you can try to catch the error in a particular scope. This way, it won’t propagate to other section of the code.

try
{
//Run some code here
}
catch(err)
{
//Handle errors here
}

This is pretty good when you are trying to debug one of the many function in your JavaScript.

Catch them all

The last one i am going to show you is to catch any one of the error into a particular function instead of using multiple try and catch.

function handleError(e)
{
alert(’An error has occurred!\n’+e);
return true;
}
window.onerror = handleError;

This will handle any error occurs in your JavaScript code to the function ‘handleError’. You will want to use this at the end of your script. Especially if you want to be informed whether a particular function or script has malfunction and the users are not reporting. Basically, what you can do is to gather all information and placed them into a String or JSON. Using ajax to delivery these information to your email or database. This way, your support team will have an idea which part are having problems and your system will be more reliable. (testing doesn’t means 100% bug free) The information that you may want to know are usually located at Navigator Object in JavaScript.

Summary

These are the methods i usually look at when debugging my own client script. It might not be everything but i hope it can be useful to some of you out there. Hope you learn something!

原文来自于:http://hungred.com/2009/08/04/useful-information/ways-debug-jquery-javascript-codes/

Author: Clay Lua