<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title type="text">博客园_坐看云起</title><subtitle type="text">人类没有热情，世界将会怎样</subtitle><id>http://feed.cnblogs.com/blog/u/13559/rss</id><updated>2012-05-31T01:16:20Z</updated><author><name>坐看云起</name><uri>http://www.cnblogs.com/hsxixi/</uri></author><generator>feed.cnblogs.com</generator><link rel="alternate" type="text/html" href="http://www.cnblogs.com/hsxixi/"/><link rel="self" type="application/atom+xml" href="http://feed.cnblogs.com/blog/u/13559/rss"/><entry><id>http://www.cnblogs.com/hsxixi/archive/2011/12/26/2302679.html</id><title type="text">大家都可以拖动的web小方块——Node.js摸石头系列之七</title><summary type="text">系列目录：Node.js摸石头系列目录 上一回聊天室的代码，我曾经答应在下一讲进行详细的解释，对不起，我食言了。因为今天我写了个小东东想和大家分享。那个，那个详细解释放到下一回吧。咳，咳……一、 还记得 Flash 的 Share Object 吗？没错，咱们不用插件就实现他。 flash 中有一个 share object ，可以让大家通过网络共享一个对象。曾经有个示例，就是甲拖动屏幕上的小球，乙的屏幕上的小球也同样被拖动了，乙也同样可以拖动的动作共享给甲。当初看到这个例子时，我觉得好神奇啊。可是一打听，完成这样的功能需要 Flash Media Server，这玩意是要钱钱地。不过没关系，</summary><published>2011-12-26T15:41:00Z</published><updated>2011-12-26T15:41:00Z</updated><author><name>坐看云起</name><uri>http://www.cnblogs.com/hsxixi/</uri></author><link rel="alternate" href="http://www.cnblogs.com/hsxixi/archive/2011/12/26/2302679.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/hsxixi/archive/2011/12/26/2302679.html"/><content type="html">&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;系列目录：&lt;a href="http://www.cnblogs.com/hsxixi/archive/2011/12/19/2293393.html"&gt;Node.js摸石头系列目录&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp; 上一回聊天室的代码，我曾经答应在下一讲进行详细的解释，对不起，我食言了。因为今天我写了个小东东想和大家分享。那个，那个详细解释放到下一回吧。咳，咳&amp;hellip;&amp;hellip;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;一、 还记得 Flash 的 Share Object 吗？没错，咱们不用插件就实现他。&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp; flash 中有一个 share object ，可以让大家通过网络共享一个对象。曾经有个示例，就是甲拖动屏幕上的小球，乙的屏幕上的小球也同样被拖动了，乙也同样可以拖动的动作共享给甲。当初看到这个例子时，我觉得好神奇啊。可是一打听，完成这样的功能需要 Flash Media Server，这玩意是要钱钱地。不过没关系，利用前面我们摸索出来的知识，我们已经可以实现这个案例了，而且，咱们不用插件！爽吧。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 有图有真相：&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/hsxixi/201112/201112262337583980.png"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="shareobject" src="http://images.cnblogs.com/cnblogs_com/hsxixi/201112/201112262338079365.png" alt="shareobject" width="644" height="427" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 如上图，拖动任意一页面红色方块，其他页面的方块会得到同步。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;二、上源码&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 源码&lt;a href="http://files.cnblogs.com/hsxixi/shareobject.rar"&gt;在这&lt;/a&gt;，解开用 node 执行 app.js 就可以了。 仅仅需要 socket.io 模块，放心，我也压进去了，所以您不用安装了。哦，对了，用了 jquery , 直接连 google 放互联网上的库的，主要是避免太多的代码给您造成混淆。我力图把代码精简到最少，方便您阅读。怎么样？我是个很体贴的男人吧。（广告语N句，略&amp;hellip;&amp;hellip;）&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;三、想说明什么？&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 还是那句，没有做不到，就怕想不到。任何事物在被创造出来之前，都已经在我们的大脑里造了一遍了。所以，尽情的去梦想吧&amp;hellip;&amp;hellip;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 发现直接上代码真是轻松啊，哈哈。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/hsxixi/aggbug/2302679.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/hsxixi/archive/2011/12/26/2302679.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/hsxixi/archive/2011/12/25/2300883.html</id><title type="text">实现使用Websocket通讯的聊天室——Node.js摸石头系列之六</title><summary type="text">系列目录：Node.js摸石头系列目录一、热线热线 上回我们建立了一个框架，并测试正常工作了。在测试的时候，我们得到了一段长长的 Js 代码。这段代码可是宝贝啊，这是公主送给您的话机啊，赶紧收好，用它我们就可以和公主热线啦！趁今天圣诞节，赶紧和公主说声节日快乐吧，否则可要没戏哦。 好，速度：在 chatroom 文件夹下建一个 .htm 文件，名字嘛就叫 chatClient.htm 好了。chatClient.htm 原本是一平淡无奇的文件，不过，我们把前面获得的“话机”给他，他就成了我们的接线员了。作为一名充满好奇心的程序猿，我相信您已经把话机拆开，把您的爪子在话机里摸啊摸的，嗯，这个事请</summary><published>2011-12-25T06:37:00Z</published><updated>2011-12-25T06:37:00Z</updated><author><name>坐看云起</name><uri>http://www.cnblogs.com/hsxixi/</uri></author><link rel="alternate" href="http://www.cnblogs.com/hsxixi/archive/2011/12/25/2300883.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/hsxixi/archive/2011/12/25/2300883.html"/><content type="html">&lt;p&gt;&lt;strong&gt;系列目录：&lt;a href="http://www.cnblogs.com/hsxixi/archive/2011/12/19/2293393.html"&gt;Node.js摸石头系列目录&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;一、热线热线&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 上回我们建立了一个框架，并测试正常工作了。在测试的时候，我们得到了一段长长的 Js 代码。这段代码可是宝贝啊，这是公主送给您的话机啊，赶紧收好，用它我们就可以和公主热线啦！趁今天圣诞节，赶紧和公主说声节日快乐吧，否则可要没戏哦。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 好，速度：在 chatroom 文件夹下建一个 .htm 文件，名字嘛就叫 chatClient.htm 好了。chatClient.htm 原本是一平淡无奇的文件，不过，我们把前面获得的&amp;ldquo;话机&amp;rdquo;给他，他就成了我们的接线员了。作为一名充满好奇心的程序猿，我相信您已经把话机拆开，把您的爪子在话机里摸啊摸的，嗯，这个事请等等再干，我们现在要做的，是从外面使用它，而不是研究它的原理。咱不能等把电视机怎么干活的弄明白再来看电视，您说是吧？&lt;/p&gt;&amp;lt;html&amp;gt;&lt;br/&gt;&amp;lt;head&amp;gt;&lt;br/&gt;&amp;lt;title&amp;gt;Chat Room&amp;lt;/title&amp;gt;&lt;br/&gt;&amp;lt;script src="http://localhost:888/socket.io/socket.io.js"&amp;gt;&amp;lt;/script&amp;gt;&lt;br/&gt;&amp;lt;script type="text/javascript"&amp;gt;&lt;br/&gt;//TODO 这里是负责建立热线的代码 &lt;br/&gt;// TODO 这里负责接收和传送消息的代码&lt;br/&gt;&amp;lt;/script&amp;gt;&lt;br/&gt;&amp;lt;/head&amp;gt;&lt;br/&gt;&amp;lt;body&amp;gt;&lt;br/&gt;&amp;lt;h1&amp;gt;Chat Room&amp;lt;/h1&amp;gt;&lt;br/&gt;&amp;lt;div id="chatbox"&amp;gt;&amp;lt;/div&amp;gt;&lt;br/&gt;&amp;lt;/body&amp;gt;&lt;br/&gt;&amp;lt;/html&amp;gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 好了，激动人心的时刻就要到了，我们要建立一条热线了，在一个美丽的圣诞节，和一位美丽的公主，建立一条畅通无阻的双向全双工的 web 史上史无前例的&amp;hellip;&amp;hellip;谁踩我？哦，哦上代码：&lt;/p&gt;&lt;blockquote style='border:2px solid #EFEFEF;color:#333333;padding:5px 10px;'&gt;&lt;p&gt;//TODO 这里是负责建立热线的代码&lt;/p&gt;&lt;p&gt;var hotline = io.connect(&amp;lsquo;http://localhost:888&amp;rsquo;);&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 将上述代码插入前面的 chatroom.htm 文件，运行服务器端 app.js 文件，然后，用浏览器打开 chatroom.htm 文件，观察服务器控制台：&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;a href="http://images.cnblogs.com/cnblogs_com/hsxixi/201112/201112251418163562.jpg"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="chatroom01" src="http://images.cnblogs.com/cnblogs_com/hsxixi/201112/201112251418178055.jpg" alt="chatroom01" width="621" height="196" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 如果看到我们控制台上出现了我们自己打印的连接成功的信息，那么这条热线就宣布成功。好吧，提醒下我们在服务器端怎么写的 ( app.js 文件里 )：&lt;/p&gt;// WebSocket 协议握手成功&lt;br/&gt;io.sockets.on('connection',function(socket) {&lt;br/&gt;    console.log("[SERVER]Connection OK!");&lt;br/&gt;});&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 提醒注意一下，这里的连接事件是 io.sockets.on 上，和我们后面拿到单个 socket ，在 socket.on 上挂事件有点区别，我坦白，在这里我折腾了好一会，等到我发现问题，不禁忿恨自己的莽撞！粗心~有眼无珠~&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;二、卿卿我我&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 热线建好了，开始亲密接触吧。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 客户端，我们可以用刚才拿到的 hotline 的 emit 方法来发送消息， on 方法来处理接收到的消息。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 服务器端，您注意到这里：&lt;/p&gt;io.sockets.on('connection', //'connection' 是socket.io 保留的，不能错哦&lt;br/&gt;              function( socket ) { //socket 就是我们的热线了&lt;br/&gt;&lt;br/&gt;socket.emit('sSayhello',{hi:'Happy new year.'});//'sSayhello'是我们自定义的，客户端听取的时候要指定同样的事件名&lt;br/&gt;socket.on('cSayhello',function(data){//'cSayhello'需要和客户端发送时定义的事件名相同&lt;br/&gt;console.log('[CLIENT]Client say hi:' );&lt;br/&gt;console.log(data);&lt;br/&gt;});&lt;br/&gt;});&lt;br/&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;三、示例源码&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 请原谅我直接上&lt;a href="http://files.cnblogs.com/hsxixi/NodeJsChatroom.rar"&gt;源码&lt;/a&gt;了，好困啊，迷糊中&amp;hellip;&amp;hellip;zzzZZZ&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 我想该说的我基本都说了，有什么问题请留言吧。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 祝大家圣诞节快乐！！！新年快乐！！！合家安康！！！&lt;/p&gt;&lt;img src="http://www.cnblogs.com/hsxixi/aggbug/2300883.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/hsxixi/archive/2011/12/25/2300883.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/hsxixi/archive/2011/12/24/2300641.html</id><title type="text">WebSocket 一场Web 通讯革命悄然来临——Node.js摸石头系列之五</title><summary type="text">系列目录：Node.js摸石头系列目录 从这回开始，我们来搭建一个简单的聊天室。因为 http 协议是无状态的，搭建聊天室这样的事从来都让人觉得疙疙瘩瘩的不是那么顺理成章。如果不使用 flash、applet 等浏览器插件的话，我们需要定期轮询服务器来获取大家的聊天信息。这造成了一定的延迟和大量的网络通讯。 不过，随着 HTML5 的浮出水面，这一情况有望彻底改观了。在 HTML5 的众多特性中，有一个总是悄悄站在幕后的大哥级人物，他就是 WebSocket 。WebSocket 实在是太强大了，Firefox 浏览器在支持一段时间后，觉得实在不能保证这位大哥不会干出点什么出格的事，把他打入冷</summary><published>2011-12-24T13:34:00Z</published><updated>2011-12-24T13:34:00Z</updated><author><name>坐看云起</name><uri>http://www.cnblogs.com/hsxixi/</uri></author><link rel="alternate" href="http://www.cnblogs.com/hsxixi/archive/2011/12/24/2300641.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/hsxixi/archive/2011/12/24/2300641.html"/><content type="html">&lt;p&gt;&lt;strong&gt;系列目录：&lt;a href="http://www.cnblogs.com/hsxixi/archive/2011/12/19/2293393.html"&gt;Node.js摸石头系列目录&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 从这回开始，我们来搭建一个简单的聊天室。因为 http 协议是无状态的，搭建聊天室这样的事从来都让人觉得疙疙瘩瘩的不是那么顺理成章。如果不使用 flash、applet 等浏览器插件的话，我们需要定期轮询服务器来获取大家的聊天信息。这造成了一定的延迟和大量的网络通讯。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 不过，随着 HTML5 的浮出水面，这一情况有望彻底改观了。在 HTML5 的众多特性中，有一个总是悄悄站在幕后的大哥级人物，他就是 WebSocket 。WebSocket 实在是太强大了，Firefox 浏览器在支持一段时间后，觉得实在不能保证这位大哥不会干出点什么出格的事，把他打入冷宫。可是正如毛遂说的，钉子放在口袋里，迟早都会冒出头的。现在最新版的 Chrome 、 Firefox&amp;nbsp; 均支持 WebSocket ，还有 IE 10 据说也将支持。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;一、WebSocket 是什么？&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 在说明 WebSocket 的时候，我们需要和 HTTP 对比来看，才会发现他的价值。&lt;/p&gt;&lt;table style="color: #000000; width: 550px;" border="1" cellspacing="0" cellpadding="15"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td valign="top" width="375"&gt;&lt;p align="right"&gt;&lt;strong&gt;&lt;span style="font-size: small;"&gt;HTTP&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;&lt;td valign="top" width="375"&gt;&lt;p align="left"&gt;&lt;strong&gt;&lt;span style="font-size: small;"&gt;WebSocket&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign="top" width="375"&gt;&lt;p align="right"&gt;双向、但是半双工&lt;/p&gt;&lt;/td&gt;&lt;td valign="top" width="375"&gt;&lt;p align="left"&gt;双向全双工&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign="top" width="375"&gt;&lt;p align="right"&gt;无状态&lt;/p&gt;&lt;/td&gt;&lt;td valign="top" width="375"&gt;&lt;p align="left"&gt;持续连接&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign="top" width="375"&gt;&lt;p align="right"&gt;高延迟&lt;/p&gt;&lt;/td&gt;&lt;td valign="top" width="375"&gt;&lt;p align="left"&gt;实时，事件驱动&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign="top" width="375"&gt;&lt;p align="right"&gt;高带宽消耗&lt;/p&gt;&lt;/td&gt;&lt;td valign="top" width="375"&gt;&lt;p align="left"&gt;低带宽消耗&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign="top" width="375"&gt;&lt;p align="right"&gt;面向文档设计&lt;/p&gt;&lt;/td&gt;&lt;td valign="top" width="375"&gt;&lt;p align="left"&gt;文档、二进制均可，客户端不局限于浏览器&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 好了，比也比完了，如果你还有点迷糊的话，哎，那我辛苦点，打个比方好了。我们把服务器比做一位美丽的公主，我们就是那苦命的追求者，之一。 http 时代：我们写了一封信(request)，交给书童，快，送信去，路上别偷懒。书童到了公主的宫殿，在门口被拦了下来，交出路条(request headers)，哦，进去吧。还好，公主对我们也还算热情，很快写好了信(response)，放进信封，贴上标签(response headers) ，交给书童。书童再屁颠屁颠跑回来交给我们。随着我们和公主感情的不断升温，我们开始豢养一群名叫阿贾克斯的信鸽，这样，就可以很快地把我们写的小诗小词送给公主了。公主如果想我们的时候，也可以在有信鸽来的时候，把她的手帕啊什么的栓在鸽子腿上给我们捎回来。HTML5 时代来了，我们和公主的关系也开始如胶似漆起来，光靠信件和便签已经不能满足了，还好，我们有 WebSocket ，只要我们让书童送去一封信，WebSocket 就会来在我们和公主之间架起一条电话热线，这样公主说话您立刻就能听见，您说话公主也立刻能听见，当然，因为这条热线是双向全双工的，你们还可以一起合唱一首小情歌。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 好了，说下个人的理解，不知道对不对，权当参考：WebSocket 就是通过 http 协议实现握手的 socket 。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 下面是摘自 Kaazing&amp;nbsp; 《WebSocket &amp;ndash;The Web Communication Revolution 》 中的一副图：&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;a href="http://images.cnblogs.com/cnblogs_com/hsxixi/201112/201112242121408903.png"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="websocket" src="http://images.cnblogs.com/cnblogs_com/hsxixi/201112/201112242121408936.png" alt="websocket" width="640" height="415" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;二、WebSocket 能干什么？&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 理论上，socket 能干什么，他就能干什么。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 这个问号的答案是无限的，我们看看这个&lt;a href="http://code.google.com/p/quake2-gwt-port" target="_blank"&gt;在线版的 Quake 游戏&lt;/a&gt;吧，也许他能点亮我们的大脑。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;strong&gt;家庭作业：&lt;/strong&gt;和你的本我、自我、大我、小我开个头脑风暴会，讨论 WebSocket 对 Web 应用开发的深刻影响。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&amp;nbsp;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;三、WebSocket 协议与 Socket.IO 模块&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; WebSocket 规范由客户端和服务器端规范分别组成。客户端由 W3C 制订，服务器端规范由 IETF 制订。Node.js 的第三方模块 &lt;a href="http://socket.io/" target="_blank"&gt;Socket.IO&lt;/a&gt; 提供在 Node.js 上使用 WebSocket 协议的能力。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 说得已经够多了，下面动手了。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 建一个项目文件夹，这里我用 chatroom 好了，您自便。打开命令行窗口，移步到 chatroom 目录下，键入如下命令：&lt;/p&gt;&lt;blockquote style='border:2px solid #EFEFEF;color:#333333;padding:5px 10px;'&gt;&lt;p&gt;&lt;span style="color: #4b4b4b;"&gt;D:\chatroom&amp;gt;&lt;strong&gt; npm install socket.io &amp;ndash;d&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 见图：(-d 参数可以使我们能够观察到安装的详细情况，但有资料说 &amp;ndash;d 是安装齐所有依赖包，不管了，加上总比不加好，是吧？)&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/hsxixi/201112/201112242301154519.jpg"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="安装socket.io" src="http://images.cnblogs.com/cnblogs_com/hsxixi/201112/201112242301165698.jpg" alt="安装socket.io" width="864" height="1084" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-weight: normal;"&gt;如果最后出现&amp;ldquo; npm info ok&amp;nbsp;&amp;nbsp; &amp;rdquo;，恭喜你，socket.io 模块安装成功。查看 chatroom 目录，得到如下结构：&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/hsxixi/201112/201112242301164302.jpg"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="dir" src="http://images.cnblogs.com/cnblogs_com/hsxixi/201112/201112242301169319.jpg" alt="dir" width="385" height="484" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;四、还是先打地基&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 准备工作完成后，我们还是先写一个最最最简的架子，然后测试他。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 请看代码：&lt;/p&gt;/* 平安夜快乐之聊天室框架 */&lt;br/&gt;&lt;br/&gt;//照例先引入模块，这次我们需要 http 和 socket.io 两个&lt;br/&gt;var http = require('http'),&lt;br/&gt;socketio = require('socket.io');&lt;br/&gt;&lt;br/&gt;//注意，和前面的区别是我们需要拿到 http 创建的服务器实例&lt;br/&gt;var app = http.createServer(function(request,response){&lt;br/&gt;//TODO 后面我们会在这把聊天室页面发回去，不过现在我们简单地提示就好了。&lt;br/&gt;response.end('Server ok.');&lt;br/&gt;}) ;&lt;br/&gt;&lt;br/&gt;//http 服务开始侦听&lt;br/&gt;app.listen(888);&lt;br/&gt;console.log("Http Server start at 888");&lt;br/&gt;&lt;br/&gt;// socket.io 开始侦听&lt;br/&gt;var io = socketio.listen(app);&lt;br/&gt;&lt;br/&gt;// WebSocket 协议握手成功&lt;br/&gt;io.sockets.on('connection',function(socket) {&lt;br/&gt;console.log("Websocket connect ok ...");&lt;br/&gt;});&lt;br/&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 保持为 app.js 文件。运行。&lt;/p&gt;&lt;blockquote style='border:2px solid #EFEFEF;color:#333333;padding:5px 10px;'&gt;&lt;p&gt;&lt;span style="color: #4b4b4b;"&gt;D:\chatroom&amp;gt; &lt;strong&gt;node app.js&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 如果见到如下图，那么恭喜你，WebSocket 已经准备好来为我们的聊天室服务了。&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/hsxixi/201112/201112242301176287.jpg"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="chatroom01" src="http://images.cnblogs.com/cnblogs_com/hsxixi/201112/201112242301171304.jpg" alt="chatroom01" width="564" height="282" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 看提示第一行是我们输出的说明 http 服务启动的信息，第二行是 Node.js ，或者准确地说是 Socket.IO 给我们的提示信息，真体贴啊。听是在听了，那么他们有没有谎报军情呢？试试看就知道了。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 请打开浏览器，等等，什么浏览器都可以吗？你不是说只有 chrome 和 火狐？ 呃，差点忘了，Socket.IO 不仅帮助我们实现了 WebSocket 协议，还帮助我们提高了浏览器的兼容性，现在已经支持 IE5+、Safari 3+、 Chrome 4+、火狐 3+、Opera 10.61+，还支持一些手机和平板上得浏览器。&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&amp;nbsp;&amp;nbsp; 请在地址栏键入：&lt;/li&gt;&lt;/ul&gt;&lt;blockquote style='border:2px solid #EFEFEF;color:#333333;padding:5px 10px;'&gt;&lt;p&gt;&lt;a href="http://localhost:888/socket.io/socket.io.js"&gt;http://localhost:888/socket.io/socket.io.js&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 观察控制台和浏览器，你会发现控制台提示你： debug &amp;ndash; served static content /socket.io.js ，而浏览器我们也得到了一段，不，一大段 js 代码，这说明我们的任务完成了。 Http 服务正常，WebSocket 服务正常，火箭即将发射！&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;----------------------- 平安夜的分割线，祝大家平安夜快乐 -----------------------------------------&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 我知道您有疑问，那段 js 代码是什么？哪里来的。嗯，欲知后事如何，请听下回分解。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/hsxixi/aggbug/2300641.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/hsxixi/archive/2011/12/24/2300641.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/hsxixi/archive/2011/12/23/2298507.html</id><title type="text">完成静态服务器——Node.js摸石头系列之四</title><summary type="text">系列目录：Node.js摸石头系列目录一、一个错误引发的摸索 上回我们在获取 request 对象的 headers 属性的 'user-agent’ 属性时，我使用了 request.headers.user-agent 这样的语法，谢谢网友artwl的提醒，这样写经实验是不行的。可是，为什么不行呢？这件事让我迷惑了。Js 中对象可以理解为属性的集合，属性的构成是键值对，Function 并不搞特殊化，和其他类型一视同仁。属性的值可以通过 object.key 或者 object[‘key’] 的方式来访问。问题出在哪里呢？上网一顿猛摸，无果。后来观察观察 headers 对象：he</summary><published>2011-12-22T16:13:00Z</published><updated>2011-12-22T16:13:00Z</updated><author><name>坐看云起</name><uri>http://www.cnblogs.com/hsxixi/</uri></author><link rel="alternate" href="http://www.cnblogs.com/hsxixi/archive/2011/12/23/2298507.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/hsxixi/archive/2011/12/23/2298507.html"/><content type="html">&lt;p&gt;&lt;strong&gt;系列目录：&lt;a href="http://www.cnblogs.com/hsxixi/archive/2011/12/19/2293393.html"&gt;Node.js摸石头系列目录&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&amp;nbsp;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;一、一个错误引发的摸索&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 上回我们在获取 request 对象的 headers 属性的 'user-agent&amp;rsquo;&amp;nbsp; 属性时，我使用了 request.headers.user-agent 这样的语法，谢谢网友&lt;a href="http://www.cnblogs.com/artwl/"&gt;artwl&lt;/a&gt;的提醒，这样写经实验是不行的。可是，为什么不行呢？这件事让我迷惑了。Js 中对象可以理解为属性的集合，属性的构成是键值对，Function 并不搞特殊化，和其他类型一视同仁。属性的值可以通过 object.key 或者 object[&amp;lsquo;key&amp;rsquo;] 的方式来访问。问题出在哪里呢？上网一顿猛摸，无果。后来观察观察 headers 对象：&lt;/p&gt;headers:   { host: 'localhost:888',&lt;br/&gt;     connection: 'keep-alive',&lt;br/&gt;     'cache-control': 'max-age=0',&lt;br/&gt;     'user-agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.202 Safari/535.1 CoolNovoChromePlus/1.6.4.30',&lt;br/&gt;     accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',&lt;br/&gt;     'accept-encoding': 'gzip,deflate,sdch',&lt;br/&gt;     'accept-language': 'zh-CN,zh;q=0.8',&lt;br/&gt;     'accept-charset': 'GBK,utf-8;q=0.7,*;q=0.3' }&lt;p&gt;&amp;nbsp;&amp;nbsp; 发现所有加了引号的键全部都有 '-' 啊，万恶的横杠啊，原来如此。&lt;/p&gt;&lt;blockquote style='border:2px solid #EFEFEF;color:#333333;padding:5px 10px;'&gt;&lt;p&gt;&lt;span style="color: #4b4b4b;"&gt;&lt;strong&gt;提醒：&lt;/strong&gt;键名称如果有 '-' 、空格等貌似非法的字符，Js 是很宽容的，不过要求你用引号括起来。而访问时也无法再用圆点加键名的方式来获取值，需要用方括号加引号的方式。&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 两句话可以说清楚的事，罗嗦了半天。其实想说的是，小石头让咱卡壳是常态，摸他，排除他。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 另外，如果您希望摸一摸某个对象，可以在 repl 环境下，把这个对象打印出来。比如，前面我们引入的 http 模块，可以 repl 提示符下键入：&lt;/p&gt;&lt;blockquote style='border:2px solid #EFEFEF;color:#333333;padding:5px 10px;'&gt;&lt;p&gt;&lt;span style="color: #4b4b4b;"&gt;D:&amp;gt; &lt;strong&gt;node&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #4b4b4b;"&gt;&amp;gt; &lt;strong&gt;require(&amp;lsquo;http&amp;rsquo;)&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;您会得到下图：&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/hsxixi/201112/201112221612247325.jpg"&gt;&lt;img style="display: block; float: none; margin-left: auto; margin-right: auto; border: 0px;" title="http" src="http://images.cnblogs.com/cnblogs_com/hsxixi/201112/20111222161226870.jpg" alt="http" width="675" height="412" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 你看，状态代码都不用查文档了吧？&lt;/p&gt;&lt;p&gt;&lt;strong&gt;二、读写文件&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 为了完成搭建静态服务器的任务，我们需要文件 I/O ，node.js 内置了 fs 模块，引入就可以读写文件了。请按下列方式组织目录：&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; MyHttpServer&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; |_____&amp;nbsp; app.js&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; |_____&amp;nbsp; webroot&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; |_____&amp;nbsp; index.htm&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 这里 webroot 文件夹就是我们静态页面的家了，我们希望以后把页面往里面一丢，就能从客户端访问。index.htm 文件里你随便贴几行字进去好了。一会我们要把他们从文件里读出来，显示在控制台并发送给浏览器。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 在写代码之前，我们先用前面的方法查看 fs 模块：&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/hsxixi/201112/201112221701126002.jpg"&gt;&lt;img style="display: inline; border: 0px;" title="fs" src="http://images.cnblogs.com/cnblogs_com/hsxixi/201112/201112221701123527.jpg" alt="fs" width="240" height="208" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp; fs 里方法真多啊。现在到了我们查阅文档的时候了。去&lt;a href="http://nodejs.org/docs/latest/api/index.html" target="_blank"&gt;官网文档&lt;/a&gt;，查到 fs.readFile 了吗？OK，就用他。测试该方法的代码就不单独写了，建议您自己先写一个，小步快跑，是学习的好方法，在编程上也适用，这样可以避免遇到问题时难以定位问题范围，可以不断地给自己小小地鼓励。直接上代码：&lt;/p&gt;/* Read a file and put to user agent */&lt;br/&gt;var http = require('http'),&lt;br/&gt;fs = require('fs');&lt;br/&gt;&lt;br/&gt;http.createServer(function(request, response){&lt;br/&gt;//读文件，读完后写入response,文件名系硬编码&lt;br/&gt;var path = __dirname + '/webroot/index.htm';&lt;br/&gt;fs.readFile( path,'utf-8', function(err,data) { //读出的内容在data里&lt;br/&gt;//在 console 打印&lt;br/&gt;//console.log(path);&lt;br/&gt;console.log(data);&lt;br/&gt;response.end(data);&lt;br/&gt;});&lt;br/&gt;}).listen(888);&lt;br/&gt;console.log('Server start at port 888.');&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 上面代码有个全局属性 __dirname ，说明下，就是当前运行代码所处的目录。查下文档赫然白底黑字地写着。嗯？怎么还有这么行字：&lt;code&gt;__dirname&lt;/code&gt; isn't actually a global but rather local to each module. 乖乖个隆地洞，差点弄错了，原来这玩意是相对于每个模块的。另外，请注意，是两个下划线哦。_ _ d i r n a m e 。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;三、分析请求路径&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 上节我们实现了读取文本文件，并送到客户端浏览器的工作。但是读取的文件名是硬编码在代码里的。现在，我们需要让用户来指定他需要什么文件，然后读出来给发过去。而用户指定的路径和文件名这个信息，正如我们前面所说的，是通过 request 传过来的，你一定还记得在系列三里，我们曾经将 request 在服务端后台打印出来过，而 request 的众多的属性里，有一个为 url 属性。是的，通常我们都是通过 url 来映射文件的路径的。不过，到了现在 MVC 和 REST 时代，情况开始变得有些复杂，暂且不提。下面我们要慢慢加快速度了。我会把一些解释逐渐移到代码的注释里面。所以，请看代码。呃，看代码之前，一条 url 一般可以分成主机地址、路径和键值对们，这个事你懂的。呃，有位园友希望讲细一点，好吧，如果你不觉得啰嗦的话，请做下图的试验：&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/10005/2011122221125489.jpg" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 我们尝试引入url模块，用这个工具来解析了一串示例，得到一个对象。其中 pathname 就是我们要的，不过现在我们需要将它映射为我们服务器端的绝对地址。好了，来试试：&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;/* Map the url path to serverpath */&lt;br/&gt;&lt;br/&gt;var http = require('http'),&lt;br/&gt;fs = require('fs'),&lt;br/&gt;urlutil = require('url');//node.js 推荐变量名与模块同名，这里为了防止误解，暂时改下&lt;br/&gt;&lt;br/&gt;http.createServer(function(request, response){&lt;br/&gt;var path = urlutil.parse(request.url).pathname;&lt;br/&gt;console.log(path);&lt;br/&gt;//映射本地&lt;br/&gt;var absPath = __dirname + "/webroot" + path;&lt;br/&gt;console.log("Path at Server: " + absPath);&lt;br/&gt;}).listen(888);&lt;br/&gt;console.log('Server start in port 888.');&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 好任务完成。现在我们要把文件发给浏览器了。&lt;/p&gt;var http = require('http'),&lt;br/&gt;fs = require('fs'),&lt;br/&gt;urlutil = require('url'),&lt;br/&gt;path = require('path');&lt;br/&gt;&lt;br/&gt;http.createServer(function(request, response){&lt;br/&gt;//get path from request's url&lt;br/&gt;var urlpath = urlutil.parse(request.url).pathname;&lt;br/&gt;//map the path to server path&lt;br/&gt;var absPath = __dirname + "/webroot" + urlpath;&lt;br/&gt;//test whether the file is exists first&lt;br/&gt;path.exists(absPath, function(exists) {&lt;br/&gt;if(exists) {&lt;br/&gt;//if ok&lt;br/&gt;fs.readFile(absPath,function(err, data) {&lt;br/&gt;//our work is here&lt;br/&gt;if(err) throw err;&lt;br/&gt;console.log(data);&lt;br/&gt;response.write(data);&lt;br/&gt;response.end();&lt;br/&gt;});&lt;br/&gt;} else {&lt;br/&gt;//show 404&lt;br/&gt;response.end('404 File not found.');&lt;br/&gt;}&lt;br/&gt;});&lt;br/&gt;}).listen(888);&lt;br/&gt;console.log('Server start in port 888.');&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 嗯，代码很完美的实现了我们的任务。当然，还有点小问题是需要我们改进的。不过先休息下，找点形容词来赞美自己吧，对自己不要太吝啬了，反正也没人听见，是不是？&lt;/p&gt;&lt;p&gt;&lt;strong&gt;四、MIME&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 上面的代码还有一点不足，就是仅仅能够读出文本文件，而且控制台的提示也是乱乱的看不清楚。一个一个来。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 首先把控制台的事搞定。只需要在读文件的时候指定编码就可以了，比如：readFile(absPath,&amp;rsquo;utf-8&amp;rsquo;,function(&amp;hellip;&amp;nbsp; 就可以了。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 剩下的就是读写不同格式文件的问题了。为了告诉浏览器我们发给他的是什么类型的文件，需要给 response 写个头信息，然后发给浏览器，浏览器根据这个信息来确定发来的是什么类型的内容。这个信息仍然是个键值对，键是 Content-Type ，顾名思义，就是内容类型了。值是什么呢？大家知道，因为服务器和浏览器都是不同的开发者开发的，所以这个事需要沟通好，否则你说文件类型是文本，他理解成图片，那不是麻烦了？&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 而避免这个麻烦的东东就是MIME了。关于MIME请参考&lt;a href="http://www.w3school.com.cn/media/media_mimeref.asp" target="_blank"&gt;这里&lt;/a&gt;，不多说什么了，我们需要做的就是把这页的列表弄下来，放进自己的代码。为了清晰起见，丢进一个模块吧，模块名 mime 好了。很自然的，我们想到用一个对象来表示这个列表。&lt;/p&gt;exports.types = {&lt;br/&gt;'323':'text/h323',&lt;br/&gt;acx:'application/internet-property-stream',&lt;br/&gt;ai:'application/postscript',&lt;br/&gt;aif:'audio/x-aiff',&lt;br/&gt;aifc:'audio/x-aiff',&lt;br/&gt;aiff:'audio/x-aiff',&lt;br/&gt;asf:'video/x-ms-asf',&lt;br/&gt;asr:'video/x-ms-asf',&lt;br/&gt;asx:'video/x-ms-asf',&lt;br/&gt;au:'audio/basic',&lt;br/&gt;avi:'video/x-msvideo',&lt;br/&gt;axs:'application/olescript',&lt;br/&gt;bas:'text/plain',&lt;br/&gt;bcpio:'application/x-bcpio',&lt;br/&gt;bin:'application/octet-stream',&lt;br/&gt;bmp:'image/bmp',&lt;br/&gt;c:'text/plain',&lt;br/&gt;cat:'application/vnd.ms-pkiseccat',&lt;br/&gt;cdf:'application/x-cdf',&lt;br/&gt;cer:'application/x-x509-ca-cert',&lt;br/&gt;'class':'application/octet-stream',&lt;br/&gt;clp:'application/x-msclip',&lt;br/&gt;cmx:'image/x-cmx',&lt;br/&gt;cod:'image/cis-cod',&lt;br/&gt;cpio:'application/x-cpio',&lt;br/&gt;crd:'application/x-mscardfile',&lt;br/&gt;crl:'application/pkix-crl',&lt;br/&gt;crt:'application/x-x509-ca-cert',&lt;br/&gt;csh:'application/x-csh',&lt;br/&gt;css:'text/css',&lt;br/&gt;dcr:'application/x-director',&lt;br/&gt;der:'application/x-x509-ca-cert',&lt;br/&gt;dir:'application/x-director',&lt;br/&gt;dll:'application/x-msdownload',&lt;br/&gt;dms:'application/octet-stream',&lt;br/&gt;doc:'application/msword',&lt;br/&gt;dot:'application/msword',&lt;br/&gt;dvi:'application/x-dvi',&lt;br/&gt;dxr:'application/x-director',&lt;br/&gt;eps:'application/postscript',&lt;br/&gt;etx:'text/x-setext',&lt;br/&gt;evy:'application/envoy',&lt;br/&gt;exe:'application/octet-stream',&lt;br/&gt;fif:'application/fractals',&lt;br/&gt;flr:'x-world/x-vrml',&lt;br/&gt;gif:'image/gif',&lt;br/&gt;gtar:'application/x-gtar',&lt;br/&gt;gz:'application/x-gzip',&lt;br/&gt;h:'text/plain',&lt;br/&gt;hdf:'application/x-hdf',&lt;br/&gt;hlp:'application/winhlp',&lt;br/&gt;hqx:'application/mac-binhex40',&lt;br/&gt;hta:'application/hta',&lt;br/&gt;htc:'text/x-component',&lt;br/&gt;htm:'text/html',&lt;br/&gt;html:'text/html',&lt;br/&gt;htt:'text/webviewhtml',&lt;br/&gt;ico:'image/x-icon',&lt;br/&gt;ief:'image/ief',&lt;br/&gt;iii:'application/x-iphone',&lt;br/&gt;ins:'application/x-internet-signup',&lt;br/&gt;isp:'application/x-internet-signup',&lt;br/&gt;jfif:'image/pipeg',&lt;br/&gt;jpe:'image/jpeg',&lt;br/&gt;jpeg:'image/jpeg',&lt;br/&gt;jpg:'image/jpeg',&lt;br/&gt;js:'application/x-javascript',&lt;br/&gt;latex:'application/x-latex',&lt;br/&gt;lha:'application/octet-stream',&lt;br/&gt;lsf:'video/x-la-asf',&lt;br/&gt;lsx:'video/x-la-asf',&lt;br/&gt;lzh:'application/octet-stream',&lt;br/&gt;m13:'application/x-msmediaview',&lt;br/&gt;m14:'application/x-msmediaview',&lt;br/&gt;m3u:'audio/x-mpegurl',&lt;br/&gt;man:'application/x-troff-man',&lt;br/&gt;mdb:'application/x-msaccess',&lt;br/&gt;me:'application/x-troff-me',&lt;br/&gt;mht:'message/rfc822',&lt;br/&gt;mhtml:'message/rfc822',&lt;br/&gt;mid:'audio/mid',&lt;br/&gt;mny:'application/x-msmoney',&lt;br/&gt;mov:'video/quicktime',&lt;br/&gt;movie:'video/x-sgi-movie',&lt;br/&gt;mp2:'video/mpeg',&lt;br/&gt;mp3:'audio/mpeg',&lt;br/&gt;mpa:'video/mpeg',&lt;br/&gt;mpe:'video/mpeg',&lt;br/&gt;mpeg:'video/mpeg',&lt;br/&gt;mpg:'video/mpeg',&lt;br/&gt;mpp:'application/vnd.ms-project',&lt;br/&gt;mpv2:'video/mpeg',&lt;br/&gt;ms:'application/x-troff-ms',&lt;br/&gt;mvb:'application/x-msmediaview',&lt;br/&gt;nws:'message/rfc822',&lt;br/&gt;oda:'application/oda',&lt;br/&gt;p10:'application/pkcs10',&lt;br/&gt;p12:'application/x-pkcs12',&lt;br/&gt;p7b:'application/x-pkcs7-certificates',&lt;br/&gt;p7c:'application/x-pkcs7-mime',&lt;br/&gt;p7m:'application/x-pkcs7-mime',&lt;br/&gt;p7r:'application/x-pkcs7-certreqresp',&lt;br/&gt;p7s:'application/x-pkcs7-signature',&lt;br/&gt;pbm:'image/x-portable-bitmap',&lt;br/&gt;pdf:'application/pdf',&lt;br/&gt;pfx:'application/x-pkcs12',&lt;br/&gt;pgm:'image/x-portable-graymap',&lt;br/&gt;pko:'application/ynd.ms-pkipko',&lt;br/&gt;pma:'application/x-perfmon',&lt;br/&gt;pmc:'application/x-perfmon',&lt;br/&gt;pml:'application/x-perfmon',&lt;br/&gt;pmr:'application/x-perfmon',&lt;br/&gt;pmw:'application/x-perfmon',&lt;br/&gt;pnm:'image/x-portable-anymap',&lt;br/&gt;pot:'application/vnd.ms-powerpoint',&lt;br/&gt;ppm:'image/x-portable-pixmap',&lt;br/&gt;pps:'application/vnd.ms-powerpoint',&lt;br/&gt;ppt:'application/vnd.ms-powerpoint',&lt;br/&gt;prf:'application/pics-rules',&lt;br/&gt;ps:'application/postscript',&lt;br/&gt;pub:'application/x-mspublisher',&lt;br/&gt;qt:'video/quicktime',&lt;br/&gt;ra:'audio/x-pn-realaudio',&lt;br/&gt;ram:'audio/x-pn-realaudio',&lt;br/&gt;ras:'image/x-cmu-raster',&lt;br/&gt;rgb:'image/x-rgb',&lt;br/&gt;rmi:'audio/mid',&lt;br/&gt;roff:'application/x-troff',&lt;br/&gt;rtf:'application/rtf',&lt;br/&gt;rtx:'text/richtext',&lt;br/&gt;scd:'application/x-msschedule',&lt;br/&gt;sct:'text/scriptlet',&lt;br/&gt;setpay:'application/set-payment-initiation',&lt;br/&gt;setreg:'application/set-registration-initiation',&lt;br/&gt;sh:'application/x-sh',&lt;br/&gt;shar:'application/x-shar',&lt;br/&gt;sit:'application/x-stuffit',&lt;br/&gt;snd:'audio/basic',&lt;br/&gt;spc:'application/x-pkcs7-certificates',&lt;br/&gt;spl:'application/futuresplash',&lt;br/&gt;src:'application/x-wais-source',&lt;br/&gt;sst:'application/vnd.ms-pkicertstore',&lt;br/&gt;stl:'application/vnd.ms-pkistl',&lt;br/&gt;stm:'text/html',&lt;br/&gt;svg:'image/svg+xml',&lt;br/&gt;sv4cpio:'application/x-sv4cpio',&lt;br/&gt;sv4crc:'application/x-sv4crc',&lt;br/&gt;swf:'application/x-shockwave-flash',&lt;br/&gt;t:'application/x-troff',&lt;br/&gt;tar:'application/x-tar',&lt;br/&gt;tcl:'application/x-tcl',&lt;br/&gt;tex:'application/x-tex',&lt;br/&gt;texi:'application/x-texinfo',&lt;br/&gt;texinfo:'application/x-texinfo',&lt;br/&gt;tgz:'application/x-compressed',&lt;br/&gt;tif:'image/tiff',&lt;br/&gt;tiff:'image/tiff',&lt;br/&gt;tr:'application/x-troff',&lt;br/&gt;trm:'application/x-msterminal',&lt;br/&gt;tsv:'text/tab-separated-values',&lt;br/&gt;txt:'text/plain',&lt;br/&gt;uls:'text/iuls',&lt;br/&gt;ustar:'application/x-ustar',&lt;br/&gt;vcf:'text/x-vcard',&lt;br/&gt;vrml:'x-world/x-vrml',&lt;br/&gt;wav:'audio/x-wav',&lt;br/&gt;wcm:'application/vnd.ms-works',&lt;br/&gt;wdb:'application/vnd.ms-works',&lt;br/&gt;wks:'application/vnd.ms-works',&lt;br/&gt;wmf:'application/x-msmetafile',&lt;br/&gt;wps:'application/vnd.ms-works',&lt;br/&gt;wri:'application/x-mswrite',&lt;br/&gt;wrl:'x-world/x-vrml',&lt;br/&gt;wrz:'x-world/x-vrml',&lt;br/&gt;xaf:'x-world/x-vrml',&lt;br/&gt;xbm:'image/x-xbitmap',&lt;br/&gt;xla:'application/vnd.ms-excel',&lt;br/&gt;xlc:'application/vnd.ms-excel',&lt;br/&gt;xlm:'application/vnd.ms-excel',&lt;br/&gt;xls:'application/vnd.ms-excel',&lt;br/&gt;xlt:'application/vnd.ms-excel',&lt;br/&gt;xlw:'application/vnd.ms-excel',&lt;br/&gt;xof:'x-world/x-vrml',&lt;br/&gt;xpm:'image/x-xpixmap',&lt;br/&gt;xwd:'image/x-xwindowdump',&lt;br/&gt;z:'application/x-compress',&lt;br/&gt;zip:'application/zip'&lt;br/&gt;}&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 类型比较多，所以很长，但结构很简单。注意我们在模块里，可以把需要暴露出去的东东链到 exports 下就可以了。把这个文件存为 mime.js ，后面我们就可以用&lt;/p&gt;&lt;blockquote style='border:2px solid #EFEFEF;color:#333333;padding:5px 10px;'&gt;&lt;p&gt;var mime = require(&amp;lsquo;./mime&amp;rsquo;)&amp;nbsp;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 这样的语法来访问了。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 万事具备，只欠东风了，离胜利只有一步之遥了。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;五、完成&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp; 完成的代码：&lt;/p&gt;/* Final Server */&lt;br/&gt;&lt;br/&gt;var http = require('http'),&lt;br/&gt;fs = require('fs'),&lt;br/&gt;urlutil = require('url'),&lt;br/&gt;path = require('path'),&lt;br/&gt;mime = require('./mime');&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;http.createServer(function(request, response){&lt;br/&gt;//get path from request's url&lt;br/&gt;var urlpath = urlutil.parse(request.url).pathname;&lt;br/&gt;//map the path to server path&lt;br/&gt;var absPath = __dirname + "/webroot" + urlpath;&lt;br/&gt;&lt;br/&gt;//test whether the file is exists first&lt;br/&gt;path.exists(absPath, function(exists) {&lt;br/&gt;if(exists) {&lt;br/&gt;//二进制方式读取文件&lt;br/&gt;fs.readFile(absPath,'binary',function(err, data) {&lt;br/&gt;//our work is here&lt;br/&gt;if(err) throw err;&lt;br/&gt;&lt;br/&gt;//获取合适的 MIME 类型并写入 response 头信息&lt;br/&gt;var ext = path.extname(urlpath);&lt;br/&gt;ext = ext ? ext.slice(1) : 'unknown';&lt;br/&gt;console.log(ext);&lt;br/&gt;var contentType = mime.types[ext] || "text/plain";&lt;br/&gt;console.log(contentType);&lt;br/&gt;response.writeHead(200,{'Content-Type':contentType});&lt;br/&gt;//console.log(data);&lt;br/&gt;//使用二进制模式写&lt;br/&gt;response.write(data,'binary');&lt;br/&gt;response.end();&lt;br/&gt;});&lt;br/&gt;} else {&lt;br/&gt;//show 404&lt;br/&gt;response.end('404 File not found.');&lt;br/&gt;}&lt;br/&gt;});&lt;br/&gt;}).listen(888);&lt;br/&gt;console.log('Server start in port 888.');&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 猛然发现我们居然实现了Apache、IIS 的基本功能。好了，可以洗洗睡了。大家伙晚安。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 差点忘了，下一回我们会进入聊天室的任务。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/hsxixi/aggbug/2298507.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/hsxixi/archive/2011/12/23/2298507.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/hsxixi/archive/2011/12/21/2296444.html</id><title type="text">完成HelloWorld——Node.js摸石头系列三</title><summary type="text">系列目录：Node.js摸石头系列目录一、完成HelloWorld 上回我们说到，使用 node.js ，我们可以迅速架起一个 http 服务器。不过上次咱们仅仅是在后台看到了客户端发来了访问，还没把 “Hello World” 给发出去呢。好，说干就干。 大家都明白，我们的Web应用抽象起来就是客户端发出请求，请求到达服务器后，服务器经过一番捣鼓，给客户端发回一个应答。“请求”我们一般抽象成 request，“应答”是 response。服务器和客户端（一般也就是浏览器啦，但是绝不局限于浏览器哦。）之间交流的语言就是 HTTP 协议了。至于服务器怎么折腾出一个应答来的，就八仙过海，各显神通了</summary><published>2011-12-21T15:20:00Z</published><updated>2011-12-21T15:20:00Z</updated><author><name>坐看云起</name><uri>http://www.cnblogs.com/hsxixi/</uri></author><link rel="alternate" href="http://www.cnblogs.com/hsxixi/archive/2011/12/21/2296444.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/hsxixi/archive/2011/12/21/2296444.html"/><content type="html">&lt;p&gt;系列目录：&lt;a href="http://www.cnblogs.com/hsxixi/archive/2011/12/19/2293393.html"&gt;Node.js摸石头系列目录&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;一、完成HelloWorld&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 上回我们说到，使用 node.js ，我们可以迅速架起一个 http 服务器。不过上次咱们仅仅是在后台看到了客户端发来了访问，还没把&amp;nbsp; &amp;ldquo;Hello World&amp;rdquo; 给发出去呢。好，说干就干。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 大家都明白，我们的Web应用抽象起来就是客户端发出请求，请求到达服务器后，服务器经过一番捣鼓，给客户端发回一个应答。&amp;ldquo;请求&amp;rdquo;我们一般抽象成 request，&amp;ldquo;应答&amp;rdquo;是 response。服务器和客户端（一般也就是浏览器啦，但是绝不局限于浏览器哦。）之间交流的语言就是 HTTP 协议了。至于服务器怎么折腾出一个应答来的，就八仙过海，各显神通了。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 总之，Web 应用中两个重量级的东东就是： Request ， Response 。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 前面我们说到，每次有访问进来，我们的代码都会跑一遍。现在的问题是，在我们的代码里，怎么抓到客户端发来的 request , 然后，到哪里去找这个 response ，好把我们捣鼓出来的东西放进去，发给客户端呢？答案是，只要我们把他们作为参数交给 tellme 函数(你可以给这个函数取任何名字甚至不给他名字)，然后，当请求到达时，node.js 就会把客户的请求封装成 request ，预备发给客户的应答封装成 response 。我们拿到 request ，看看他请求些什么，再折腾些东西（读出个文件也好，去查数据库也好，随便你了。）丢进 response ，发给客户端。&lt;/p&gt;&lt;blockquote style='border:2px solid #EFEFEF;color:#333333;padding:5px 10px;'&gt;&lt;p&gt;&lt;span style="color: #4b4b4b;"&gt;&lt;strong&gt;提醒：&lt;/strong&gt;这种利用参数进行传递是 node.js 的常态。&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;请看代码：&lt;/p&gt;/* Request and Response */&lt;br/&gt;&lt;br/&gt;var http = require('http');&lt;br/&gt;&lt;br/&gt;http.createServer(&lt;br/&gt;&lt;br/&gt;function(request, //客户端发来的请求，node.js 帮我们封装成 request 对象&lt;br/&gt; response //我们利用response,向客户端发送回答&lt;br/&gt; ){&lt;br/&gt;//在控制台显示request对象&lt;br/&gt;console.log(request);&lt;br/&gt;//总算完成 hello world 了。&lt;br/&gt;response.end('Hello world!');&lt;br/&gt;&lt;br/&gt;}).listen(888);&lt;br/&gt;&lt;br/&gt;console.log('Server start at 888');&lt;p&gt;运行他，用浏览器访问他。现在，在浏览器得到了咱们盼望已久的&amp;ldquo;Hello world!&amp;rdquo;，真不容易啊。再看看服务器的控制台，这么一大串的是什么？这个就是 Request 了。如果您熟悉 Json 格式，我想您已经看明白了，不熟悉也没关系，其实很简单，无非就是花括号( {} )标示对象，对象里各个属性用逗号( , )隔开，每个属性都由一个&amp;ldquo;键&amp;rdquo;和一个&amp;ldquo;值&amp;rdquo;组成，中间用冒号 ( : )分开，是不是很简单呢。&lt;/p&gt;{ socket:{ ... },&lt;br/&gt;  ...&lt;br/&gt;  headers:   { host: 'localhost:888',&lt;br/&gt;     connection: 'keep-alive',&lt;br/&gt;     'cache-control': 'max-age=0',&lt;br/&gt;     'user-agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.202 Safari/535.1 CoolNovoChromePlus/1.6.4.30',&lt;br/&gt;     accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',&lt;br/&gt;     'accept-encoding': 'gzip,deflate,sdch',&lt;br/&gt;     'accept-language': 'zh-CN,zh;q=0.8',&lt;br/&gt;     'accept-charset': 'GBK,utf-8;q=0.7,*;q=0.3' },&lt;br/&gt;&lt;br/&gt;  ...&lt;br/&gt;   url:'/',&lt;br/&gt;   method:'GET',&lt;br/&gt;   ...&lt;br/&gt;}&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 观察 request 对象，我们可以找到一些我们熟悉的东西。比如：request.url、request.method、比如 headers 。好，下面我们来把后台让我们眼花缭乱的输出简化一下：&lt;/p&gt;/* Request and Response */&lt;br/&gt;&lt;br/&gt;var http = require('http');&lt;br/&gt;http.createServer(&lt;br/&gt;function(request,  response ){&lt;br/&gt;//只显示request对象的某几个属性&lt;br/&gt;console.log(request.url);&lt;br/&gt;console.log(request.headers['user-agent']);&lt;br/&gt;//回应客户端&lt;br/&gt;response.end('Hello world!');&lt;br/&gt;}).listen(888);&lt;br/&gt;&lt;br/&gt;console.log('Server start at 888');&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 重启服务，访问服务器，观察后台。发现我们每刷新一次浏览器，其实进来了两个request,一个是访问&amp;rsquo;/&amp;rsquo;的，另一个是找 &amp;lsquo;favicon.ico ' 的，当然，很抱歉，目前还没有这个网站图标给他。控制台还显示了客户端用来访问服务器的浏览器的类型和版本。如果还想知道些什么，自己去 request 里面去挖吧。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;系列四我们将完成一个静态的 Web 服务器，只要把静态页面丢进某个文件夹，就可以用浏览器访问。另由于昨天去考驾照理论课，进度有些慢了，对不住。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/hsxixi/aggbug/2296444.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/hsxixi/archive/2011/12/21/2296444.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/hsxixi/archive/2011/12/19/2293393.html</id><title type="text">Node.js摸石头系列目录</title><summary type="text">1、Node.js 的安装和控制台命令——Node.js摸石头系列之一2、架一个HTTP服务——Node.js摸石头系列之二3、完成HelloWorld——Node.js摸石头系列之三4、完成静态服务器——Node.js摸石头系列之四5、WebSocket 一场Web 通讯革命悄然来临——Node.js摸石头系列之五6、实现使用Websocket通讯的聊天室——Node.js摸石头系列之六7、大家都可以拖动的web小方块——Node.js摸石头系列之七</summary><published>2011-12-19T06:57:00Z</published><updated>2011-12-19T06:57:00Z</updated><author><name>坐看云起</name><uri>http://www.cnblogs.com/hsxixi/</uri></author><link rel="alternate" href="http://www.cnblogs.com/hsxixi/archive/2011/12/19/2293393.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/hsxixi/archive/2011/12/19/2293393.html"/><content type="html">&lt;p&gt;1、&lt;a href="http://www.cnblogs.com/hsxixi/archive/2011/12/17/2290976.html"&gt;Node.js 的安装和控制台命令&amp;mdash;&amp;mdash;Node.js摸石头系列之一&lt;/a&gt;&lt;/p&gt;&lt;p&gt;2、&lt;a href="http://www.cnblogs.com/hsxixi/archive/2011/12/19/2291854.html"&gt;架一个HTTP服务&amp;mdash;&amp;mdash;Node.js摸石头系列之二&lt;/a&gt;&lt;/p&gt;&lt;p&gt;3、&lt;a href="http://www.cnblogs.com/hsxixi/archive/2011/12/21/2296444.html" target="_blank"&gt;完成HelloWorld&amp;mdash;&amp;mdash;Node.js摸石头系列之三&lt;/a&gt;&lt;/p&gt;&lt;p&gt;4、&lt;a id="ctl03_TitleUrl" class="postTitle2" href="http://www.cnblogs.com/hsxixi/archive/2011/12/23/2298507.html" target="_blank"&gt;完成静态服务器&amp;mdash;&amp;mdash;Node.js摸石头系列之四&lt;/a&gt;&lt;/p&gt;&lt;p&gt;5、&lt;a id="homepage1_HomePageDays_DaysList_DayItem_0_DayList_0_TitleUrl_0" class="postTitle2" href="http://www.cnblogs.com/hsxixi/archive/2011/12/24/2300641.html"&gt;WebSocket 一场Web 通讯革命悄然来临&amp;mdash;&amp;mdash;Node.js摸石头系列之五&lt;/a&gt;&lt;/p&gt;&lt;p&gt;6、&lt;a id="homepage1_HomePageDays_DaysList_DayItem_0_DayList_0_TitleUrl_0" class="postTitle2" href="http://www.cnblogs.com/hsxixi/archive/2011/12/25/2300883.html"&gt;实现使用Websocket通讯的聊天室&amp;mdash;&amp;mdash;Node.js摸石头系列之六&lt;/a&gt;&lt;/p&gt;&lt;p&gt;7、&lt;a id="ctl03_TitleUrl" class="postTitle2" href="http://www.cnblogs.com/hsxixi/archive/2011/12/26/2302679.html"&gt;大家都可以拖动的web小方块&amp;mdash;&amp;mdash;Node.js摸石头系列之七&lt;/a&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/hsxixi/aggbug/2293393.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/hsxixi/archive/2011/12/19/2293393.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/hsxixi/archive/2011/12/19/2291854.html</id><title type="text">架一个HTTP服务——Node.js摸石头系列之二</title><summary type="text">系列目录：Node.js摸石头系列目录 摸石头就是摸着石头过河的意思。Node.js 正在快速发展，有广阔的应用前景，不过文档和参考资料也不是十分完备。这个系列其实就是我的读书笔记了。我学习的方式基本上是鲸吞和试验两大法宝。这两个法宝很有效，但同时也耗费很大的时间和精力。所以，希望把自己趟过的路，插上路标，帮助童鞋们节约点时间。 上回说道：在 Windows 平台(本系列都是基于Windows平台，后面就不再注明了)，node.js 可以精简到一个可执行文件，运行这个文件，我们就得到了一个控制台，在这个控制台，我们可以以 REPL (Read-Eval-Print-Loop) 的方式交互的执行</summary><published>2011-12-19T04:05:00Z</published><updated>2011-12-19T04:05:00Z</updated><author><name>坐看云起</name><uri>http://www.cnblogs.com/hsxixi/</uri></author><link rel="alternate" href="http://www.cnblogs.com/hsxixi/archive/2011/12/19/2291854.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/hsxixi/archive/2011/12/19/2291854.html"/><content type="html">&lt;p&gt;系列目录：&lt;a class="postTitle2" href="http://www.cnblogs.com/hsxixi/archive/2011/12/19/2293393.html" target="_blank"&gt;Node.js摸石头系列目录&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 摸石头就是摸着石头过河的意思。Node.js 正在快速发展，有广阔的应用前景，不过文档和参考资料也不是十分完备。这个系列其实就是我的读书笔记了。我学习的方式基本上是鲸吞和试验两大法宝。这两个法宝很有效，但同时也耗费很大的时间和精力。所以，希望把自己趟过的路，插上路标，帮助童鞋们节约点时间。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 上回说道：在 Windows 平台(本系列都是基于Windows平台，后面就不再注明了)，node.js 可以精简到一个可执行文件，运行这个文件，我们就得到了一个控制台，在这个控制台，我们可以以 REPL (Read-Eval-Print-Loop) 的方式交互的执行js代码。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;一、批量执行代码&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 好，顺理成章的下一个问题就是：如何批量执行 js 代码呢？回答是可以将 js 代码放进一个文件，然后将文件的路径作为参数告诉 node.exe 文件就可以了。就象 Java 执行一段代码一样。(粗体是我们键入内容，下同)&lt;/p&gt;&lt;blockquote style='border:2px solid #EFEFEF;color:#333333;padding:5px 10px;'&gt;&lt;p&gt;&lt;span style="color: #4b4b4b;"&gt;d: \myNodeJsDemo&amp;gt;&lt;strong&gt;node&amp;nbsp; index.js&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 一个比较容易犯的错误就是键入 node 后回车，已经进入了 REPL 环境再执行上诉内容，那么你会得到新一行的三个点&amp;ldquo;&amp;hellip;&amp;rdquo;，告诉你 node.js 在等待你完成 js 代码。你可以按 &amp;lt;ctrl&amp;gt;d退出 REPL 环境，在系统提示符下重来就可以了。&lt;/p&gt;&lt;blockquote style='border:2px solid #EFEFEF;color:#333333;padding:5px 10px;'&gt;&lt;p&gt;&lt;span style="color: #4b4b4b;"&gt;REPL 环境下，如果遇到连续的&amp;ldquo;&amp;hellip;&amp;rdquo;，想放弃录入退回到 REPL 提示符，可以按 &amp;lt;ctrl&amp;gt;C，鉴于 js 复杂的嵌套，我想这是会经常遇到的。&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;strong&gt;二、前端呢？还是后端？这是个问题。&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 在大家的印象中，Javascript 很少逃出浏览器的五指山，所以，估计您和我一样，第一次接触到 Node.js 这个名字时，会误以为是一个新的前端框架。咱们误会人家人家了，Node.js 诞生的目的是为了建立服务器端应用的。所以，这个摸石头系列我们有两个任务要完成：&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1、建立一个简单的静态web服务器。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 2、架一个聊天室。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 注意，以上两个任务只能使用 node.js 及其第三方模块，不可使用IIS、Apahe、Nginx等Web服务器。想一想，如果使用c、c++、java、c#等来实现，这两个任务够您忙活一下的吧。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 而使用 node.js 来实现，你可以用两行代码就实现第一个任务。怎么样，期待吧，嘿嘿。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;三、模块模块&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 学 C 语言的时候大家都明白，没有 stdio.h ，连最简单的屏幕打印都没法做。任何语言，失去了强大类库的支持，都会变的弱弱的。或者，换一个角度，任何成熟的语言，都是采用把强大的功能打包成类库的方式，实现语言的高扩展的。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 现在明白为什么 Javascript 总是那么弱不禁风的样子了吗？嗯，就是因为缺少强大的类库啊。所以，一帮大牛开始考虑干这件事了，这个项目就是 &lt;a href="http://www.commonjs.org/"&gt;CommonJS&lt;/a&gt; 。CommonJS 希望实现一个 Javascript 标准类库(或者说，定义了一套标准)，使开发者能够利用 Javascirpt 来开发下列类型的应用：&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1、服务器端应用；&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 2、命令行工具；&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3、桌面基于 GUI 应用&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 4、混合应用（Titanium, Adobe AIR）&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; node.js 是 Common.JS 的实现者之一。好了，require 函数该出场了。在 CommonJS 规范中，使用这个函数来引入别的模块，说白了，就和 include(C) 、 import(JAVA) 、 using (C#) 等类似。比如，node.js 内置了个模块，专门帮助我们实现 http 服务。我们只需要：&lt;/p&gt;&lt;blockquote style='border:2px solid #EFEFEF;color:#333333;padding:5px 10px;'&gt;&lt;p&gt;&lt;span style="color: #4b4b4b;"&gt;var http = require(&amp;lsquo;http&amp;rsquo;);&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 就可以开始使用该模块的功能了。截止2012年12月19日，node.js 官网现在已经注册了 5747 个&lt;a href="http://search.npmjs.org/" target="_blank"&gt;第三方模块&lt;/a&gt;。安装这些模块也非常的简单，不过，还是先来完成任务一吧。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;四、HTTP 服务之 Hello World&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 如果我说只用两行代码就实现一个 http 服务器，您不会用鸡蛋砸我吧？等，等等&amp;hellip;&amp;hellip; @#$*@(@!_#&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 实在要砸我，鸡蛋多浪费，换成小妹妹的香包什么的多好。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 好吧，第一句上面我们已经写出来了。下面看完整代码！砸我！&lt;/p&gt;//最简单 node.js http 服务器&lt;br/&gt;&lt;br/&gt;//引入模块&lt;br/&gt;var http = require('http);&lt;br/&gt;&lt;br/&gt;//创建一个服务并启动他&lt;br/&gt;http.createServer().listen();&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 好了，任务完成，保存成 app.js 文件，并用：node app.js 运行吧。现在你可以用浏览器访问了，地址是：&lt;a href="http://localhost"&gt;http://localhost&lt;/a&gt; 。什么？浏览器什么反应都没有？控制台也只有光标在闪啊闪？嗯，咱们换个端口吧，默认的80端口往往和我们其他的 web 服务有冲突：&lt;/p&gt;var http = require('http');&lt;br/&gt;//换成在888端口监听&lt;br/&gt;http.createServer().listen(888);&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 相应的，访问地址也需要换一下：&lt;a href="http://localhost:888"&gt;http://localhost:888&lt;/a&gt; 。还是没反应？好吧，为了说服你我们的服务器已经完美的在工作了，告诉你一个小秘密吧。http.createServer 其实是可以带参数的。你也知道，js 是个很自由的语言，参数是可以省略的，所以我就省略了。而且，你也知道， js 自由到可以用函数来做参数，嗯，您猜对了，http.createServer 的参数确实应该是一个函数。这个函数在每次有 http 请求进来的时候就会跑一遍，也就是说，您每用浏览器访问一次上面的地址，我们传进去的函数就运行一遍。OK，上试验：&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;var http = require('http');&lt;br/&gt;http.createServer(&lt;br/&gt;//这里我们传进一个函数做参数&lt;br/&gt;tellme&lt;br/&gt;).listen(888);&lt;br/&gt;&lt;br/&gt;//请求进来时候执行的代码&lt;br/&gt;function tellme(){&lt;br/&gt;//在后台控制台提示有访问进来了。&lt;br/&gt;console.log('I receive a quest.');&lt;br/&gt;}&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 好，现在再访问试试。浏览器还是什么都没有。不过，每次我们刷新浏览器，后台都会告诉我们访问进来了。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 好了，回家吃饭。后面内容，放第三篇唠叨吧。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/hsxixi/aggbug/2291854.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/hsxixi/archive/2011/12/19/2291854.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/hsxixi/archive/2011/12/17/2290976.html</id><title type="text">Node.js 的安装和控制台命令——Node.js摸石头系列之一</title><summary type="text">一、Node.js简介 为了说服您阅读这份简单的说明，我想先给Node.js做点广告还是有必要的。先看看都有谁在用Node.js吧，跟着业界老大混，总是大差不差的。首先，微软的云服务Azure已经开始支持Node.js、还有就是Ebay、Yahoo、Linkedin，是不是有点精神了？嗯，我们继续。下面是官网的自我介绍： Node.js is a platform built on Chrome's JavaScript runtime for easily building fast, scalable network applications. Node.js uses an ev</summary><published>2011-12-17T03:39:00Z</published><updated>2011-12-17T03:39:00Z</updated><author><name>坐看云起</name><uri>http://www.cnblogs.com/hsxixi/</uri></author><link rel="alternate" href="http://www.cnblogs.com/hsxixi/archive/2011/12/17/2290976.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/hsxixi/archive/2011/12/17/2290976.html"/><content type="html">&lt;p&gt;&lt;strong&gt;一、Node.js简介&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 为了说服您阅读这份简单的说明，我想先给Node.js做点广告还是有必要的。先看看都有谁在用Node.js吧，跟着业界老大混，总是大差不差的。首先，微软的云服务Azure已经开始支持Node.js、还有就是Ebay、Yahoo、Linkedin，是不是有点精神了？嗯，我们继续。下面是&lt;a href="http://nodejs.org"&gt;官网&lt;/a&gt;的自我介绍：&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Node.js is a platform built on Chrome's JavaScript runtime for easily building fast, scalable network applications. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient, perfect for data-intensive real-time applications that run across distributed devices.&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Node.js 是一个平台，建立在 Chrome JavaScript 运行时之上，目的是建立快速、可伸缩的网络应用。Node.js使用事件驱动，非阻塞的 I/O 模式，这使得他是轻量而高效的，能够在分布设备上完美运行高数据吞吐的实时应用。&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 如果官网没有王婆卖瓜的话，我想您应该有兴趣花上五分钟浏览下面的内容了。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;二、安装&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;这里仅说明Windows平台安装，很简单，去官网下载安装包，运行，OK。&lt;/p&gt;&lt;p&gt;安装完毕后，也许您习惯的去找快捷方式。不好意思，虽然您眼神比我好，可是也是找不到滴。别着急，安装包默认把所有文件拷贝到了&amp;ldquo;C:\Program Files\nodejs&amp;rdquo;目录下，然后，很体贴地设置好了系统环境变量里的path，现在，请打开一个命令行窗口，输入：&lt;/p&gt;&lt;blockquote style='border:2px solid #EFEFEF;color:#333333;padding:5px 10px;'&gt;&lt;p&gt;&lt;span style="color: #4b4b4b;"&gt;&amp;gt;node&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #4b4b4b;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;如果你得到一个提示符，系统没警告说&amp;ldquo;对不起，没有此命令&amp;rdquo;，那么，恭喜，安装成功完成。如果你还想观察下nodejs的目录结构的话，也会发现超级简单，就是一个node.exe文件，还有比这更简单的吗？&lt;/p&gt;&lt;p&gt;啊？您说还有一个 npm.cmd 批处理文件和 node_modules 文件夹？那个，那个我们目前可以暂时无视。您可以删了他们而不影响 node.js 的使用。&lt;/p&gt;&lt;p&gt;不过既然提到他们，npm 是用来管理模块的，而 node.js 的魅力也在于他的模块化，内核只做内核该做的事，其他的一切，全通过模块的扩展来实现。这也为 node.js 带来了无尽可能。&lt;/p&gt;&lt;p&gt;可爱的模块们，一般就窝在 node_modules 文件夹里。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;三、控制台命令和REPL&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;好了，既然我们得到了 node.js 的提示符，也就是说我们现在是在 node.js 的环境里了。在这个环境里，您所有的 Javascript 知识都可以派上用场了，因为 node.js 使用的就是著名的 v8 引擎。补充说明一下，node.js 把这个称作Read-Eval-Print-Loop，就是说，咱们在这里就可以交互地跑 js 代码了。感觉回到了最初学 Basic 的年代啊。怀念、怀念。&lt;/p&gt;&lt;blockquote style='border:2px solid #EFEFEF;color:#333333;padding:5px 10px;'&gt;&lt;code&gt;&amp;gt; a = [ 1, 2, 3];&amp;nbsp;&lt;/code&gt;&lt;code&gt;[ &lt;span style="color: #9bbb59;"&gt;1&lt;/span&gt;, &lt;span style="color: #9bbb59;"&gt;2&lt;/span&gt;, &lt;span style="color: #9bbb59;"&gt;3&lt;/span&gt; ]&amp;nbsp;&lt;/code&gt;&lt;code&gt;&amp;gt; a.forEach(&lt;span style="color: #ffc000;"&gt;function&lt;/span&gt; (v) {&lt;/code&gt;&lt;code&gt; ...&lt;/code&gt; console.log(v);&amp;nbsp;... }); &lt;span style="color: #9bbb59;"&gt;1&lt;/span&gt;&lt;span style="color: #9bbb59;"&gt; 2&lt;/span&gt;&lt;span style="color: #9bbb59;"&gt; 3&lt;/span&gt;&lt;/blockquote&gt;&lt;code&gt;为数不多的几个控制台命令可以用 help 查到，唯一需要注意的就是别忘了这些命令前面需要带上一个小圆点：&lt;/code&gt;&lt;blockquote style='border:2px solid #EFEFEF;color:#333333;padding:5px 10px;'&gt;&lt;code&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/hsxixi/201112/201112171139118194.jpg"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="noderepl" src="http://images.cnblogs.com/cnblogs_com/hsxixi/201112/201112171139119307.jpg" alt="noderepl" border="0" /&gt;&lt;/a&gt;&lt;/code&gt;&lt;/blockquote&gt;&lt;p&gt;好了，现在可以开始您的 node.js 之旅了，当然，如果你愿意的话。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/hsxixi/aggbug/2290976.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/hsxixi/archive/2011/12/17/2290976.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/hsxixi/archive/2011/11/28/2266517.html</id><title type="text">BookMarklet：瑞士军刀你用了吗？</title><summary type="text">Bookmarklet 是一段隐藏在链接后面的js代码，可以收藏在收藏夹。通过这段代码，我们可以跨浏览器（当然，也跨平台）实现一些工具。比起浏览器插件来说，使用更加方便。典型的，dict.cn 网站的工具和有道笔记的工具。海词词典有道笔记还有jquery网站也有个。上诉两个已经是我工具箱里必不可少的工具了。把链接拖到浏览器的书签工具栏，就可以随时使用了。浏览器也许会警告你不安全，IE会，火狐和chrome不会。就他最不安全，还最装。BS他。 点下面的链接试试：我的书签看到什么了？页面左上角多了一个标签。to be continue ...</summary><published>2011-11-28T09:29:00Z</published><updated>2011-11-28T09:29:00Z</updated><author><name>坐看云起</name><uri>http://www.cnblogs.com/hsxixi/</uri></author><link rel="alternate" href="http://www.cnblogs.com/hsxixi/archive/2011/11/28/2266517.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/hsxixi/archive/2011/11/28/2266517.html"/><content type="html">&lt;p&gt;Bookmarklet 是一段隐藏在链接后面的js代码，可以收藏在收藏夹。通过这段代码，我们可以跨浏览器（当然，也跨平台）实现一些工具。比起浏览器插件来说，使用更加方便。典型的，dict.cn 网站的工具和有道笔记的工具。&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;a href="javascript:void((function()%20{var%20element=document.createElement('script');%20element.setAttribute('src',%20'http://dict.cn/hc/init.php');%20document.body.appendChild(element);})())"&gt;海词词典&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="javascript:(function(){CLIP_HOST='http://note.youdao.com/yws';try{var x=document.createElement('SCRIPT');x.type='text/javascript';x.src=CLIP_HOST+'/YNoteClipper.js?'+(new Date().getTime()/100000);x.charset='utf-8';document.getElementsByTagName('head')[0].appendChild(x);}catch(e){alert(e);}})();"&gt;有道笔记&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;还有jquery网站也有个。上诉两个已经是我工具箱里必不可少的工具了。把链接拖到浏览器的书签工具栏，就可以随时使用了。浏览器也许会警告你不安全，IE会，火狐和chrome不会。就他最不安全，还最装。BS他。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;点下面的链接试试：&lt;/p&gt;&lt;p&gt;&lt;a href="javascript:void ((function(){var element = document.createElement('script');element.setAttribute('src', 'http://files.cnblogs.com/hsxixi/MyInit.js');document.body.appendChild(element);})())"&gt;我的书签&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;看到什么了？页面左上角多了一个标签。&lt;/p&gt;&lt;p&gt;to be continue ...&lt;/p&gt;&lt;img src="http://www.cnblogs.com/hsxixi/aggbug/2266517.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/hsxixi/archive/2011/11/28/2266517.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/hsxixi/archive/2011/11/28/2265747.html</id><title type="text">Aptana studio 3 修改配色方案</title><summary type="text">默认的黑底与文字的对比度实在是太低了，看着眼睛好累。所以该个配色方案吧。修改方法：window/preferences 菜单打开配置窗口。这么多配置，去哪里找呢？配色一般是“theme”吧？好，搜搜看，在左上角的文本框里输入:theme 试试，啊哈，找到。Aptana studio/themes,应该就是他了。（为什么这么罗嗦？嗯，因为我想告诉您的是找到解决办法的过程，而不仅仅是结果。熟用搜索，防止老花！什么时候当您准备把脑袋扎进屏幕的时候，请想起这句口号。一会把这句话抄上一百遍，交给老师。当我们的软件提供太多选项给用户的时候，看着他们痛苦地把眼睛瞪得如牛眼，是不是也应该人道一点，提供个搜索框</summary><published>2011-11-28T01:07:00Z</published><updated>2011-11-28T01:07:00Z</updated><author><name>坐看云起</name><uri>http://www.cnblogs.com/hsxixi/</uri></author><link rel="alternate" href="http://www.cnblogs.com/hsxixi/archive/2011/11/28/2265747.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/hsxixi/archive/2011/11/28/2265747.html"/><content type="html">&lt;p&gt;默认的黑底与文字的对比度实在是太低了，看着眼睛好累。所以该个配色方案吧。修改方法：&lt;/p&gt;&lt;ol&gt;&lt;li&gt;window/preferences 菜单打开配置窗口。&lt;/li&gt;&lt;li&gt;这么多配置，去哪里找呢？配色一般是&amp;ldquo;theme&amp;rdquo;吧？好，搜搜看，在左上角的文本框里输入:theme 试试，啊哈，找到。Aptana studio/themes,应该就是他了。（为什么这么罗嗦？嗯，因为我想告诉您的是找到解决办法的过程，而不仅仅是结果。熟用搜索，防止老花！什么时候当您准备把脑袋扎进屏幕的时候，请想起这句口号。一会把这句话抄上一百遍，交给老师。当我们的软件提供太多选项给用户的时候，看着他们痛苦地把眼睛瞪得如牛眼，是不是也应该人道一点，提供个搜索框呢？扯远了，打住打住。）&lt;/li&gt;&lt;li&gt;这点就简单了。选个你觉得对得起您色迷迷的窗户的方案就好了。&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;没了。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/hsxixi/aggbug/2265747.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/hsxixi/archive/2011/11/28/2265747.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry></feed>
