<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2enclosuresfull.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:media="http://search.yahoo.com/mrss/" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Fdream's Blog</title>
	
	<link>http://fdream.net/blog</link>
	<description>Keep the world easy</description>
	<lastBuildDate>Mon, 21 May 2012 12:44:22 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/fdream" /><feedburner:info uri="fdream" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><itunes:explicit>no</itunes:explicit><itunes:subtitle>Keep the world easy</itunes:subtitle><item>
		<title>WebSocket Draft 10向客户端写文本数据的实现</title>
		<link>http://feedproxy.google.com/~r/fdream/~3/BHrobjXEXOg/767.aspx</link>
		<comments>http://fdream.net/blog/article/767.aspx#comments</comments>
		<pubDate>Thu, 03 Nov 2011 03:51:52 +0000</pubDate>
		<dc:creator>Fdream</dc:creator>
				<category><![CDATA[Ajax Web]]></category>
		<category><![CDATA[nodejs]]></category>
		<category><![CDATA[websocket]]></category>

		<guid isPermaLink="false">http://fdream.net/blog/?p=767</guid>
		<description><![CDATA[在Draft 10中，如果解析数据的过程弄清楚了，这个就更简单了，返回数据的格式和之前接受到的数据格式非常类似，只是你不用生成mask了，头部的其他格式还是一模一样的。 第一个字节还是固定的，是0&#215;81，意义和接受数据的意义一样，第二个字节也是，后七个位表示数据长度，由于没有mask，所以第一位是0；长度的表示方法和接受的标识方法一致，可能用7位表示，也可能用16位表示。 用NodeJS实现如下： var socketWriter = { 'draft10': function(socket, data){ var frames, length = new Buffer(data, 'utf8').length; if(data.length > 0x7d){ frames = new Buffer(4); frames[0] = 0x81; frames[1] = 0x7e; frames[2] = length >> 8; frames[3] = length &#038; &#8230; <a href="http://fdream.net/blog/article/767.aspx">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>在Draft 10中，如果解析数据的过程弄清楚了，这个就更简单了，返回数据的格式和之前接受到的数据格式非常类似，只是你不用生成mask了，头部的其他格式还是一模一样的。</p>
<p>第一个字节还是固定的，是0&#215;81，意义和接受数据的意义一样，第二个字节也是，后七个位表示数据长度，由于没有mask，所以第一位是0；长度的表示方法和接受的标识方法一致，可能用7位表示，也可能用16位表示。</p>
<p>用NodeJS实现如下：</p>
<pre lang="js">
var socketWriter = {
    'draft10': function(socket, data){
        var frames,
            length = new Buffer(data, 'utf8').length;
        if(data.length > 0x7d){
            frames = new Buffer(4);
            frames[0] = 0x81;
            frames[1] = 0x7e;
            frames[2] = length >> 8;
            frames[3] = length &#038; 0xFF; //1111 1111
        }
        else{
            frames = new Buffer(2);
            frames[0] = 0x81;
            frames[1] = length;
        }

        if (socket.writable) {
            socket.write(frames, 'binary');
            socket.write(data, 'utf8');
            return true;
        }
        return false;
    },
    'draft76': function(socket, data){
        var byteLen = Buffer.byteLength(data, 'utf8'),
            bytes = new Buffer(byteLen + 2);

        bytes[0] = 0x00;
        bytes.write(data, 1, 'utf8');
        bytes[byteLen + 1] = 0xFF;

        return socket.write(bytes);
    }
};

socketWriter['draft75'] = socketWriter['draft76'];
</pre>
<h3 class='related_post_title'>Related Posts:</h3>
<ul class='related_post'>
<li><a href='http://fdream.net/blog/article/759.aspx' title='WebSocket草案10文本数据解析实现'>WebSocket草案10文本数据解析实现</a></li>
<li><a href='http://fdream.net/blog/article/756.aspx' title='WebSocket草案10握手协议的实现'>WebSocket草案10握手协议的实现</a></li>
</ul>

<p><a href="http://feedads.g.doubleclick.net/~a/nH_IxUW12ytu9gj2ly0-BkJ3YGo/0/da"><img src="http://feedads.g.doubleclick.net/~a/nH_IxUW12ytu9gj2ly0-BkJ3YGo/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/nH_IxUW12ytu9gj2ly0-BkJ3YGo/1/da"><img src="http://feedads.g.doubleclick.net/~a/nH_IxUW12ytu9gj2ly0-BkJ3YGo/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/fdream/~4/BHrobjXEXOg" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://fdream.net/blog/article/767.aspx/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://fdream.net/blog/article/767.aspx</feedburner:origLink></item>
		<item>
		<title>WebSocket草案10文本数据解析实现</title>
		<link>http://feedproxy.google.com/~r/fdream/~3/Lr8t18AEugs/759.aspx</link>
		<comments>http://fdream.net/blog/article/759.aspx#comments</comments>
		<pubDate>Thu, 27 Oct 2011 09:04:18 +0000</pubDate>
		<dc:creator>Fdream</dc:creator>
				<category><![CDATA[Ajax Web]]></category>
		<category><![CDATA[AJAX]]></category>
		<category><![CDATA[websocket]]></category>

		<guid isPermaLink="false">http://fdream.net/blog/?p=759</guid>
		<description><![CDATA[握手协议实现了，接下来就是解析数据了，这个相对来说要麻烦很多，相比草案7.6变得更复杂了。下图是数据传输的格式： 各个值的具体含义可以参考这个中文翻译：http://blog.csdn.net/fenglibing/article/details/6852497，英文原文在这里：http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-10#section-4.2 简单概括一下就是：FIN一直为1，RSV1、RSV2、RSV3一直为0，当发送内容为文本时，opcode为1，MASK如果为1就使用掩码，需要获取四位掩码，依次轮流和数据做异或运算，第一个内容数据与第一个掩码异或，第二个内容数据与第二个掩码异或……第五个内容数据与第一个掩码异或……一直到结束，然后再对内容进行编码就可以了。 在Chrome/Firefox下面，FIN永远为1，如果只是文本消息，opcode一直是1，RSV1、RSV2、RSV3都为0，所以第一个数据是0&#215;81；MASK为1，再跟上数据长度，所以第二个数据会大于0&#215;80，由于数据长度不一样，其需要占用的字节数也不一样，因此掩码的位置也不一样。根据规范，换算下来是这样：数据总长度（包含FIN、RSV等等信息）小于0&#215;84，则掩码为第三个数据到第六个数据；数据总长度（包含FIN、RSV等等信息）小于0xfe81，则掩码为第五个数据到第八个数据；其他掩码则为第十三个数据到第十六个数据。当数据长度超过一个包的长度时，后面的数据包不再包含RIN、RSV和MASK等信息，二是直接为内容数据，需要根据上一次取到的MASK来做异或运算。在客户端主动要求断开链接时，会没有内容数据，只有头信息和掩码，长度固定为6，为了避免混淆，Chrome会保证正常内容发送时不会出现6字节的数据，基本上可以把6字节当断开连接请求处理。区分客户端主动要求断开连接和正常的连续数据包要根据长度区分：如果是连续的数据包，则已解析的包的长度会小于首包头信息里的长度，否则则认为是客户端主动要求断开链接。主动断开连接时会发送的一个额外的数据包，此时第一个字节不会为正常的0&#215;81，通常为0&#215;88，NodeJS写出来大致是这样的： module.exports = Parser; var util = require('util'), events = require('events'); /** * http.Server 数据解析类 * */ function Parser(version) { events.EventEmitter.call(this); this.version = version &#124;&#124; 'draft10'; this.length = 0; this.parsed = 0; this.maskData = []; this.frameData = &#8230; <a href="http://fdream.net/blog/article/759.aspx">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>握手协议实现了，接下来就是解析数据了，这个相对来说要麻烦很多，相比草案7.6变得更复杂了。下图是数据传输的格式：</p>
<p><a href="http://fdream.net/blog/wp-content/uploads/2011/10/websocket.png"><img class="alignnone size-full wp-image-760" title="websocket" src="http://fdream.net/blog/wp-content/uploads/2011/10/websocket.png" alt="" width="476" height="281" /></a></p>
<p>各个值的具体含义可以参考这个中文翻译：<a href="http://blog.csdn.net/fenglibing/article/details/6852497">http://blog.csdn.net/fenglibing/article/details/6852497</a>，英文原文在这里：<a href="http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-10#section-4.2">http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-10#section-4.2</a></p>
<p>简单概括一下就是：FIN一直为1，RSV1、RSV2、RSV3一直为0，当发送内容为文本时，opcode为1，MASK如果为1就使用掩码，需要获取四位掩码，依次轮流和数据做异或运算，第一个内容数据与第一个掩码异或，第二个内容数据与第二个掩码异或……第五个内容数据与第一个掩码异或……一直到结束，然后再对内容进行编码就可以了。</p>
<p>在Chrome/Firefox下面，FIN永远为1，如果只是文本消息，opcode一直是1，RSV1、RSV2、RSV3都为0，所以第一个数据是0&#215;81；MASK为1，再跟上数据长度，所以第二个数据会大于0&#215;80，由于数据长度不一样，其需要占用的字节数也不一样，因此掩码的位置也不一样。根据规范，换算下来是这样：数据总长度（包含FIN、RSV等等信息）小于0&#215;84，则掩码为第三个数据到第六个数据；数据总长度（包含FIN、RSV等等信息）小于0xfe81，则掩码为第五个数据到第八个数据；其他掩码则为第十三个数据到第十六个数据。当数据长度超过一个包的长度时，后面的数据包不再包含RIN、RSV和MASK等信息，二是直接为内容数据，需要根据上一次取到的MASK来做异或运算。<del datetime="2011-10-28T09:04:28+00:00">在客户端主动要求断开链接时，会没有内容数据，只有头信息和掩码，长度固定为6，为了避免混淆，Chrome会保证正常内容发送时不会出现6字节的数据，基本上可以把6字节当断开连接请求处理</del>。区分客户端主动要求断开连接和正常的连续数据包要根据长度区分：如果是连续的数据包，则已解析的包的长度会小于首包头信息里的长度，否则则认为是客户端主动要求断开链接。主动断开连接时会发送的一个额外的数据包，此时第一个字节不会为正常的0&#215;81，通常为0&#215;88，NodeJS写出来大致是这样的：</p>
<pre lang="js">module.exports = Parser;

var util = require('util'),
    events = require('events');

/**
* http.Server 数据解析类
* */
function Parser(version) {
     events.EventEmitter.call(this);

     this.version = version || 'draft10';
    this.length = 0;
    this.parsed = 0;
     this.maskData = [];
     this.frameData = [];
     this.order = 0;
     this.closing = false;
}

util.inherits(Parser, events.EventEmitter);

Parser.prototype.write = function(data) {
    console.log(data.length);
     dataParser[this.version](data, this);
};

// 数据解析工具
var dataParser = {
     'draft10': function(data, parser){
        var pkt, i =0, len = 0, start = 0;

        // 如果不包含包头，而且数据已经解析完成
        // 则认为这个包为结束包，首字节通常为0x88
        if(data[0] != 0x81 &amp;&amp; parser.length == 0){
            parser.emit('close');
            parser.closing = false;
            return;
        }

        // 草案10
        // 首包会包含掩码信息
        if(data[0] == 0x81){
            // 使用了掩码
            if(data[1] &gt;= 0x80){
                // 数据长度不一样，掩码位置不一样
                if(data.length &lt; 0x84){
                    // firefox下，超过一个包长度的数据会被拆分为多个包
                    // 其中首包只包含头信息，第二个字节为0xfe
                    if(data[1] == 0xfe){
                        len = data.length;
                        // firefox
                        parser.maskData = [data[len - 4], data[len - 3], data[len - 2], data[len - 1]];
                        parser.length = data[len - 5];
                        for(i = len - 6; i &gt; 1; i--){
                            parser.length += data[i] * (len - 5 - i) * 256;
                        }
                        console.log('firefox multi packages, length: ', parser.length);
                        start = data.length;
                    }
                    else{
                        // chrome
                        parser.length = data[1] - 0x80;
                        console.log('7bit, length: ', parser.length);
                        parser.maskData = [data[2], data[3], data[4], data[5]];
                        start = 6;
                    }
                }
                else if(data.length &lt; 0xfe80){                     parser.length = data[2] * 256 + data[3];                     console.log('7 + 16bit, length: ', parser.length);                     parser.maskData = [data[4], data[5], data[6], data[7]];                     start = 8;                 }                 else{                     dparser.length = data[11];                     for(i = 10; i &gt; 3; i--){
                        parser.length += data[i] * (11 - i) * 256;
                    }
                    console.log('7 + 64bit, length: ', parser.length);
                    parser.maskData = [data[12], data[13], data[14], data[15]];
                    start = 16;
                }

                for(i = start, len = data.length; i &lt; len; i++){
                    parser.frameData.push(parser.maskData[(i - start) % 4] ^ data[i]);
                }
            }
            else{
                if(data.length &lt; 0x80){
                    start = 2;
                }
                else if(data.length &lt; 0xfe81){
                    start = 4;
                }
                else{
                    start = 12;
                }
                // find contents
                parser.frameData = data.splice(start);
            }
            console.log('1st packge frame length: ', parser.frameData.length);
            if(parser.frameData.length == parser.length){
                pkt = new Buffer(parser.frameData);
                // console.log(pkt.toString('utf8', 0, pkt.length));
                parser.emit('message', pkt.toString('utf8', 0, pkt.length));
                // 数据包结束，重置长度信息
                parser.frameData = [];
                parser.length = 0;
            }
            return;
        }

        // 连续的数据包
        if(parser.maskData.length){
            // continue to parse data
            for(i = 0, l = data.length; i &lt; l; i++){
                parser.frameData.push(parser.maskData[i % 4] ^ data[i]);
            }
            console.log('frame length: ', parser.frameData.length);
            if(parser.frameData.length == parser.length){
                pkt = new Buffer(parser.frameData);
                // console.log(pkt.toString('utf8', 0, pkt.length));
                parser.emit('message', pkt.toString('utf8', 0, pkt.length));
                // 数据包结束，重置长度信息
                parser.frameData = [];
                parser.length = 0;
            }
            return;
        }
     }
};</pre>
<h3 class='related_post_title'>Related Posts:</h3>
<ul class='related_post'>
<li><a href='http://fdream.net/blog/article/756.aspx' title='WebSocket草案10握手协议的实现'>WebSocket草案10握手协议的实现</a></li>
<li><a href='http://fdream.net/blog/article/767.aspx' title='WebSocket Draft 10向客户端写文本数据的实现'>WebSocket Draft 10向客户端写文本数据的实现</a></li>
<li><a href='http://fdream.net/blog/article/702.aspx' title='Merpressor —— 在线自动合并、压缩JS文件'>Merpressor —— 在线自动合并、压缩JS文件</a></li>
<li><a href='http://fdream.net/blog/article/699.aspx' title='不安全的js写法'>不安全的js写法</a></li>
<li><a href='http://fdream.net/blog/article/698.aspx' title='全新极速CSS选择器引擎whiz'>全新极速CSS选择器引擎whiz</a></li>
</ul>

<p><a href="http://feedads.g.doubleclick.net/~a/G0Q4P-bLa8pA_0ia2XrKx1GowRE/0/da"><img src="http://feedads.g.doubleclick.net/~a/G0Q4P-bLa8pA_0ia2XrKx1GowRE/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/G0Q4P-bLa8pA_0ia2XrKx1GowRE/1/da"><img src="http://feedads.g.doubleclick.net/~a/G0Q4P-bLa8pA_0ia2XrKx1GowRE/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/fdream/~4/Lr8t18AEugs" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://fdream.net/blog/article/759.aspx/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://fdream.net/blog/article/759.aspx</feedburner:origLink></item>
		<item>
		<title>WebSocket草案10握手协议的实现</title>
		<link>http://feedproxy.google.com/~r/fdream/~3/Mo64if58WcE/756.aspx</link>
		<comments>http://fdream.net/blog/article/756.aspx#comments</comments>
		<pubDate>Thu, 27 Oct 2011 08:24:57 +0000</pubDate>
		<dc:creator>Fdream</dc:creator>
				<category><![CDATA[Ajax Web]]></category>
		<category><![CDATA[AJAX]]></category>
		<category><![CDATA[websocket]]></category>

		<guid isPermaLink="false">http://fdream.net/blog/?p=756</guid>
		<description><![CDATA[Chrome早就采用了websocket草案10的协议，很多以前支持websocket的代码突然之间都用不了了，很多作者也没空更新，索性自己看了下草案，自己实现了一套。 握手协议还是非常简单的，Chrome发过来的header大概是这样的： GET /chat HTTP/1.1 Host: server.example.com Upgrade: websocket Connection: Upgrade Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ== Sec-WebSocket-Origin: http://example.com Sec-WebSocket-Protocol: chat, superchat Sec-WebSocket-Version: 8 要答复的头大概是这样的： HTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo= 实际上这里要处理的就是算出这个Sec-WebSocket-Accept的值。这个非常简单，首先拿到Sec-WebSocket-Key，也就是dGhlIHNhbXBsZSBub25jZQ==，把它和字符串258EAFA5-E914-47DA-95CA-C5AB0DC85B11拼在一起： var key = request.headers['sec-websocket-key'] + '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'; 然后对这个key做一个SHA-1的加密，对加密后的字符串再base64就可以了，用nodejs写出来就是这样的： var &#8230; <a href="http://fdream.net/blog/article/756.aspx">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Chrome早就采用了<a title="websocket草案10" href="http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-10">websocket草案10</a>的协议，很多以前支持websocket的代码突然之间都用不了了，很多作者也没空更新，索性自己看了下草案，自己实现了一套。</p>
<p>握手协议还是非常简单的，Chrome发过来的header大概是这样的：</p>
<pre lang="js">GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Origin: http://example.com
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 8</pre>
<p>要答复的头大概是这样的：</p>
<pre lang="js">HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=</pre>
<p>实际上这里要处理的就是算出这个Sec-WebSocket-Accept的值。这个非常简单，首先拿到Sec-WebSocket-Key，也就是dGhlIHNhbXBsZSBub25jZQ==，把它和字符串258EAFA5-E914-47DA-95CA-C5AB0DC85B11拼在一起：</p>
<pre lang="js">var key = request.headers['sec-websocket-key'] + '258EAFA5-E914-47DA-95CA-C5AB0DC85B11';</pre>
<p>然后对这个key做一个SHA-1的加密，对加密后的字符串再base64就可以了，用nodejs写出来就是这样的：</p>
<pre lang="js">var sha1 = Crypto.createHash('sha1');
key = sha1.update(key).digest('base64');</pre>
<p>这个里面的key值就是最终要返回给客户端的值了，这样就算完成握手了。<br />
<h3 class='related_post_title'>Related Posts:</h3>
<ul class='related_post'>
<li><a href='http://fdream.net/blog/article/759.aspx' title='WebSocket草案10文本数据解析实现'>WebSocket草案10文本数据解析实现</a></li>
<li><a href='http://fdream.net/blog/article/767.aspx' title='WebSocket Draft 10向客户端写文本数据的实现'>WebSocket Draft 10向客户端写文本数据的实现</a></li>
<li><a href='http://fdream.net/blog/article/702.aspx' title='Merpressor —— 在线自动合并、压缩JS文件'>Merpressor —— 在线自动合并、压缩JS文件</a></li>
<li><a href='http://fdream.net/blog/article/699.aspx' title='不安全的js写法'>不安全的js写法</a></li>
<li><a href='http://fdream.net/blog/article/698.aspx' title='全新极速CSS选择器引擎whiz'>全新极速CSS选择器引擎whiz</a></li>
</ul>

<p><a href="http://feedads.g.doubleclick.net/~a/wtg7sjr4V-esSIIzCwbzFyYs00k/0/da"><img src="http://feedads.g.doubleclick.net/~a/wtg7sjr4V-esSIIzCwbzFyYs00k/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/wtg7sjr4V-esSIIzCwbzFyYs00k/1/da"><img src="http://feedads.g.doubleclick.net/~a/wtg7sjr4V-esSIIzCwbzFyYs00k/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/fdream/~4/Mo64if58WcE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://fdream.net/blog/article/756.aspx/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://fdream.net/blog/article/756.aspx</feedburner:origLink></item>
		<item>
		<title>Mac下SSH代理软件Secret Socks修改版</title>
		<link>http://feedproxy.google.com/~r/fdream/~3/4Tcua-UfYM0/742.aspx</link>
		<comments>http://fdream.net/blog/article/742.aspx#comments</comments>
		<pubDate>Sun, 02 Oct 2011 05:58:25 +0000</pubDate>
		<dc:creator>Fdream</dc:creator>
				<category><![CDATA[计算机相关]]></category>
		<category><![CDATA[mac]]></category>
		<category><![CDATA[ssh]]></category>

		<guid isPermaLink="false">http://fdream.net/blog/?p=742</guid>
		<description><![CDATA[Secret Socks是Mac下不错的SSH代理软件，不过有两点非常的不爽：一是不能记住密码（可能原作者是考虑到安全因素），二是超时时间设置得有点过短，而且不能修改，导致经常半天都连不上，实在是让人很郁闷。 令人欣慰的是，作者公开了此软件的源代码，索性直接拿来改了下，重新发布一个新版本。专门针对以上两点做了修改，基于安全因素（相对安全）考虑，给保存的密码用DES进行了加密，key是一个随机的字符串，非公开的。 打包后的文件只在Lion（10.7.x）下进行了测试，要求系统的最低版本是10.5.x，但未进行测试。 安装包下载地址：http://vdisk.weibo.com/s/IAQS(新浪微盘) 下载地址：http://115.com/file/bevneg0p#Secret-Socks.zip &#160; Related Posts: No Related Posts]]></description>
			<content:encoded><![CDATA[<p>Secret Socks是Mac下不错的SSH代理软件，不过有两点非常的不爽：一是不能记住密码（可能原作者是考虑到安全因素），二是超时时间设置得有点过短，而且不能修改，导致经常半天都连不上，实在是让人很郁闷。</p>
<p>令人欣慰的是，作者公开了此软件的源代码，索性直接拿来改了下，重新发布一个新版本。专门针对以上两点做了修改，基于安全因素（相对安全）考虑，给保存的密码用DES进行了加密，key是一个随机的字符串，非公开的。</p>
<p>打包后的文件只在Lion（10.7.x）下进行了测试，要求系统的最低版本是10.5.x，但未进行测试。</p>
<p><del datetime="2012-05-21T12:43:12+00:00">安装包下载地址：<a href="http://vdisk.weibo.com/s/IAQS" target="_blank">http://vdisk.weibo.com/s/IAQS</a>(新浪微盘)</del></p>
<p>下载地址：<a href="http://115.com/file/bevneg0p# Secret-Socks.zip" target="_blank">http://115.com/file/bevneg0p#Secret-Socks.zip</a></p>
<p><a href="http://fdream.net/blog/wp-content/uploads/2011/10/secret_socks.jpg"><img class="alignnone size-full wp-image-747" title="secret_socks" src="http://fdream.net/blog/wp-content/uploads/2011/10/secret_socks.jpg" alt="" width="617" height="523" /></a></p>
<p>&nbsp;<br />
<h3 class='related_post_title'>Related Posts:</h3>
<ul class='related_post'>
<li>No Related Posts</li>
</ul>

<p><a href="http://feedads.g.doubleclick.net/~a/0OdlYuJFsQZ5zL46R7t2TYTsqdA/0/da"><img src="http://feedads.g.doubleclick.net/~a/0OdlYuJFsQZ5zL46R7t2TYTsqdA/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/0OdlYuJFsQZ5zL46R7t2TYTsqdA/1/da"><img src="http://feedads.g.doubleclick.net/~a/0OdlYuJFsQZ5zL46R7t2TYTsqdA/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/fdream/~4/4Tcua-UfYM0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://fdream.net/blog/article/742.aspx/feed</wfw:commentRss>
		<slash:comments>15</slash:comments>
		<feedburner:origLink>http://fdream.net/blog/article/742.aspx</feedburner:origLink></item>
		<item>
		<title>js中函数预解析在Firefox下的异常表现</title>
		<link>http://feedproxy.google.com/~r/fdream/~3/FByC4c638GQ/737.aspx</link>
		<comments>http://fdream.net/blog/article/737.aspx#comments</comments>
		<pubDate>Fri, 09 Sep 2011 13:52:10 +0000</pubDate>
		<dc:creator>Fdream</dc:creator>
				<category><![CDATA[Ajax Web]]></category>
		<category><![CDATA[Firefox]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://fdream.net/blog/?p=737</guid>
		<description><![CDATA[前几天同事发现的一个诡异现象，猜猜浏览器执行下面这段代码会弹出什么提示？ if(1){ f(1); function f(a){ alert(a); } } 通常情况下，都认为javascript中function会被预解析，所以这里应该会弹出一个对话框，显示字符“1”。没错，在IE6-IE9，Chrome，Safari，Opera等待浏览器下也都是这个结果。但是偏偏Firefox有点特立独行，会提示“引用错误，f未定义”。 我们再试试，把if去掉，只留两个花括号看看： { f(1); function f(a){ alert(a); } } 还是一样！现在我们在试试几种情况： if(1){ function f(a){ alert(a); } f(1); } 这个没有问题，正常显示1，再试试这个： if(1){ function f(a){ alert(a); } } f(1); 也没有问题，再试试这个： if(0){ function f(a){ alert(a); } } &#8230; <a href="http://fdream.net/blog/article/737.aspx">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>前几天同事发现的一个诡异现象，猜猜浏览器执行下面这段代码会弹出什么提示？</p>
<pre lang="js">if(1){
    f(1);
    function f(a){
        alert(a);
    }
}</pre>
<p>通常情况下，都认为javascript中function会被预解析，所以这里应该会弹出一个对话框，显示字符“1”。没错，在IE6-IE9，Chrome，Safari，Opera等待浏览器下也都是这个结果。但是偏偏Firefox有点特立独行，会提示“引用错误，f未定义”。</p>
<p>我们再试试，把if去掉，只留两个花括号看看：</p>
<pre lang="js">{
    f(1);
    function f(a){
        alert(a);
    }
}</pre>
<p>还是一样！现在我们在试试几种情况：</p>
<pre lang="js">if(1){
    function f(a){
        alert(a);
    }
    f(1);
}</pre>
<p>这个没有问题，正常显示1，再试试这个：</p>
<pre lang="js">if(1){
    function f(a){
        alert(a);
    }
}
f(1);</pre>
<p>也没有问题，再试试这个：</p>
<pre lang="js">if(0){
    function f(a){
        alert(a);
    }
}
f(1);</pre>
<p>这个果然不正常了，提示f未定义！看来是Firefox对花括号里面的函数声明做了特殊处理，并没有对花括号内部的函数声明做预解析，而只是等到要执行的时候才去解析，也许是为了性能优化？或者这本身就是一个bug？<br />
<h3 class='related_post_title'>Related Posts:</h3>
<ul class='related_post'>
<li><a href='http://fdream.net/blog/article/546.aspx' title='Firefox下和IE下的单击和双击事件差异'>Firefox下和IE下的单击和双击事件差异</a></li>
<li><a href='http://fdream.net/blog/article/731.aspx' title='也谈JavaScript代码性能优化'>也谈JavaScript代码性能优化</a></li>
<li><a href='http://fdream.net/blog/article/702.aspx' title='Merpressor —— 在线自动合并、压缩JS文件'>Merpressor —— 在线自动合并、压缩JS文件</a></li>
<li><a href='http://fdream.net/blog/article/701.aspx' title='在弹出窗口用POST提交数据'>在弹出窗口用POST提交数据</a></li>
<li><a href='http://fdream.net/blog/article/699.aspx' title='不安全的js写法'>不安全的js写法</a></li>
</ul>

<p><a href="http://feedads.g.doubleclick.net/~a/Mn9PWSfGnAGqzP2FescsdQVBhTk/0/da"><img src="http://feedads.g.doubleclick.net/~a/Mn9PWSfGnAGqzP2FescsdQVBhTk/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/Mn9PWSfGnAGqzP2FescsdQVBhTk/1/da"><img src="http://feedads.g.doubleclick.net/~a/Mn9PWSfGnAGqzP2FescsdQVBhTk/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/fdream/~4/FByC4c638GQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://fdream.net/blog/article/737.aspx/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://fdream.net/blog/article/737.aspx</feedburner:origLink></item>
		<item>
		<title>解决Opera不能访问内网资源的问题</title>
		<link>http://feedproxy.google.com/~r/fdream/~3/KfP9zBCEdzY/724.aspx</link>
		<comments>http://fdream.net/blog/article/724.aspx#comments</comments>
		<pubDate>Thu, 25 Aug 2011 09:16:08 +0000</pubDate>
		<dc:creator>Fdream</dc:creator>
				<category><![CDATA[Ajax Web]]></category>
		<category><![CDATA[opera]]></category>

		<guid isPermaLink="false">http://fdream.net/blog/?p=724</guid>
		<description><![CDATA[开发测试时，经常会把公网页面上的部分域名指向内网时，在Opera下并不会发送对应请求，导致页面不正常，而几乎所有的浏览器都正常。这个并不是页面兼容性问题，这其实是Opera独有的一种安全策略。解决此问题的方法如下： 菜单-&#62;设置-&#62;首选项-&#62;高级-&#62;安全性-&#62;信任的网站-&#62;安全的内部主机-&#62;添加，输入你内网服务器的IP即可。 &#160; Related Posts: No Related Posts]]></description>
			<content:encoded><![CDATA[<p>开发测试时，经常会把公网页面上的部分域名指向内网时，在Opera下并不会发送对应请求，导致页面不正常，而几乎所有的浏览器都正常。这个并不是页面兼容性问题，这其实是Opera独有的一种安全策略。解决此问题的方法如下：</p>
<p>菜单-&gt;设置-&gt;首选项-&gt;高级-&gt;安全性-&gt;信任的网站-&gt;安全的内部主机-&gt;添加，输入你内网服务器的IP即可。</p>
<p><a href="http://fdream.net/blog/wp-content/uploads/2011/05/opera.jpg"><img class="alignnone size-medium wp-image-733" title="opera" src="http://fdream.net/blog/wp-content/uploads/2011/05/opera-300x159.jpg" alt="opera 设置" width="300" height="159" /></a></p>
<p>&nbsp;<br />
<h3 class='related_post_title'>Related Posts:</h3>
<ul class='related_post'>
<li>No Related Posts</li>
</ul>

<p><a href="http://feedads.g.doubleclick.net/~a/V-zUPvNE0p53I0yrpkQJSxG5PKg/0/da"><img src="http://feedads.g.doubleclick.net/~a/V-zUPvNE0p53I0yrpkQJSxG5PKg/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/V-zUPvNE0p53I0yrpkQJSxG5PKg/1/da"><img src="http://feedads.g.doubleclick.net/~a/V-zUPvNE0p53I0yrpkQJSxG5PKg/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/fdream/~4/KfP9zBCEdzY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://fdream.net/blog/article/724.aspx/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://fdream.net/blog/article/724.aspx</feedburner:origLink></item>
		<item>
		<title>也谈JavaScript代码性能优化</title>
		<link>http://feedproxy.google.com/~r/fdream/~3/WOoQOvq--3Y/731.aspx</link>
		<comments>http://fdream.net/blog/article/731.aspx#comments</comments>
		<pubDate>Wed, 01 Jun 2011 13:17:13 +0000</pubDate>
		<dc:creator>Fdream</dc:creator>
				<category><![CDATA[Ajax Web]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[技巧]]></category>

		<guid isPermaLink="false">http://fdream.net/blog/?p=731</guid>
		<description><![CDATA[差不多两年前写了个选择器whiz，除在DOM查找方面做了许多优化工作之外，还在代码优化上做了很多工作，一直没有分享。抽空总结一下，基本上在jQuery、Mootools和YUI的源码里面都可以看到这些写法。有些是已经在网上分享很多遍了，众所周知的，也有一些可能写了多年的JavaScript的开发人员也不一定想得到的。如果有说得不正确的地方，还请大家指出。还有特别说明的是，其中某些写法不是很推荐，虽然代码简洁了，但是有可能造成阅读困难。 1.尽量使用源生方法（Native Method） js是解释性语言，相比编译性语言执行速度要慢。如果浏览器已经实现了该方法，就不要再用js再去实现一遍了。另外，绝大部分情况下，浏览器已经实现的方法已经在算法方面做了很多优化，再重复实现一遍只是浪费时间和精力还有带宽。当然，如果你只是为了练习算法，那另当别论。 2.尽可能减少循环次数 代码的瓶颈大多在循环，少一层循环，就能数倍地提高性能。如果要对一个数组的每个元素进行多次操作，尽可能使用一次循环，多次操作，而不是多次循环，每次循环执行一次操作。尤其是在进行多个正则匹配的时候，尽可能合并正则表达式，在一次遍历中尽可能找到相应的匹配。 3.循环的另外一种写法 通常循环的写法： var objs = [obj1, obj2, obj3], i = 0; len = objs.length; for(i = 0; i &#60; len; i++){ dosth(obj); } 当循环遍历的对象是object时，可以采用下面的方式来写： var objs = [obj1, obj2, obj3], obj, i = 0; &#8230; <a href="http://fdream.net/blog/article/731.aspx">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>差不多两年前写了个<a title="全新极速CSS选择器引擎whiz" href="http://fdream.net/blog/article/698.aspx" target="_blank">选择器whiz</a>，除在DOM查找方面做了许多优化工作之外，还在代码优化上做了很多工作，一直没有分享。抽空总结一下，基本上在jQuery、Mootools和YUI的源码里面都可以看到这些写法。有些是已经在网上分享很多遍了，众所周知的，也有一些可能写了多年的JavaScript的开发人员也不一定想得到的。如果有说得不正确的地方，还请大家指出。还有特别说明的是，其中某些写法不是很推荐，虽然代码简洁了，但是有可能造成阅读困难。</p>
<h3>1.尽量使用源生方法（Native Method）</h3>
<p>js是解释性语言，相比编译性语言执行速度要慢。如果浏览器已经实现了该方法，就不要再用js再去实现一遍了。另外，绝大部分情况下，浏览器已经实现的方法已经在算法方面做了很多优化，再重复实现一遍只是浪费时间和精力还有带宽。当然，如果你只是为了练习算法，那另当别论。</p>
<h3>2.尽可能减少循环次数</h3>
<p>代码的瓶颈大多在循环，少一层循环，就能数倍地提高性能。如果要对一个数组的每个元素进行多次操作，尽可能使用一次循环，多次操作，而不是多次循环，每次循环执行一次操作。尤其是在进行多个正则匹配的时候，尽可能合并正则表达式，在一次遍历中尽可能找到相应的匹配。</p>
<h3>3.循环的另外一种写法</h3>
<p>通常循环的写法：</p>
<pre lang="js">var objs = [obj1, obj2, obj3], i = 0; len = objs.length;
for(i = 0; i &lt; len; i++){
    dosth(obj);
}</pre>
<p>当循环遍历的对象是object时，可以采用下面的方式来写：</p>
<pre lang="js">var objs = [obj1, obj2, obj3], obj, i = 0;
while(obj = objs[i++]){
    dosth(obj);
}</pre>
<p>特别注意，如果你的数组里面有可能出现0, false, null等等在条件判断为false的值，这种写法是不正确的。</p>
<h3>4.某些情况下switch的另外一种写法</h3>
<p>通常的switch写法：</p>
<pre lang="js">function fun_a(){}
function fun_b(){}
function fun_c(){}
switch(con){
    case 'a':
        fun_a();
        break;
    case 'b':
        fun_b();
        break;
    case 'c':
        fun_c();
        break;
}</pre>
<p>另外一种写法：</p>
<pre lang="js">function fun_a(){}
function fun_b(){}
function fun_c(){}
var funs = {
        'a': fun_a,
        'b': fun_b,
        'c': fun_c
    };
funs[con]();</pre>
<p>取值或者函数调用都可以用类似的方式来做。</p>
<h3>5.条件判断的另外一种写法</h3>
<p>通常情况下：</p>
<pre lang="js">if(a){
  dosth();
}</pre>
<p>可以这样写：</p>
<pre lang="js">a &amp;&amp; dosth();</pre>
<h3>6.创建对象的另外一个办法，不使用new</h3>
<p>很多时候，我们要连续创建一些简单的object对象，并且拥有默认的属性，很多人会这么写：</p>
<pre lang="js">function Klass(){
    this.prop_a = '';
    this.prop_b = [];
    this.prop_c = 0;
}
var objs = [], i = 0, obj;
while(i&lt;100){
    obj = new Klass();
    obj.prop_c = i;
    objs.push(obj);
}</pre>
<p>换种写法看看：</p>
<pre lang="js">function create(){
    return {
        prop_a : '',
        prop_b : [],
        prop_c : 0
    };
}
var objs = [], i = 0, obj;
while(i&lt;100){
    obj = create();
    obj.prop_c = i;
    objs.push(obj);
}</pre>
<p>当然还有直接声明的方式，但是复用性会差一些。</p>
<h3>7.用来做标记的变量尽可能使用布尔类型</h3>
<p>直接用true和false做标记，不要使用数字或者字符串的1和0来做标记，直接也高效。</p>
<p>其他的优化方法已经有很多分享了，大家可以<a title="Google搜索“Javascript 性能优化”" href="http://www.google.com/#sclient=psy&amp;hl=en&amp;newwindow=1&amp;safe=off&amp;source=hp&amp;q=javascript+%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96&amp;aq=f&amp;aqi=&amp;aql=&amp;oq=&amp;pbx=1&amp;bav=on.2,or.r_gc.r_pw.&amp;fp=a0dfe33164af09eb&amp;biw=1280&amp;bih=879" target="_blank">Google一下</a>，另外《javascript高级程序设计》一书中也对JavaScript性能优化做了较为详细的阐述。<br />
<h3 class='related_post_title'>Related Posts:</h3>
<ul class='related_post'>
<li><a href='http://fdream.net/blog/article/619.aspx' title='JavaScript类型转换太变态，慎用'>JavaScript类型转换太变态，慎用</a></li>
<li><a href='http://fdream.net/blog/article/549.aspx' title='让Javascript的智能提示和C#一样强悍'>让Javascript的智能提示和C#一样强悍</a></li>
<li><a href='http://fdream.net/blog/article/4.aspx' title='网页自适应不同分辨率显示'>网页自适应不同分辨率显示</a></li>
<li><a href='http://fdream.net/blog/article/737.aspx' title='js中函数预解析在Firefox下的异常表现'>js中函数预解析在Firefox下的异常表现</a></li>
<li><a href='http://fdream.net/blog/article/719.aspx' title='解决ubuntu下ibus没有输入窗口的问题'>解决ubuntu下ibus没有输入窗口的问题</a></li>
</ul>

<p><a href="http://feedads.g.doubleclick.net/~a/N6qqeL8GC0ctOUJnSVmpAXSnMYI/0/da"><img src="http://feedads.g.doubleclick.net/~a/N6qqeL8GC0ctOUJnSVmpAXSnMYI/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/N6qqeL8GC0ctOUJnSVmpAXSnMYI/1/da"><img src="http://feedads.g.doubleclick.net/~a/N6qqeL8GC0ctOUJnSVmpAXSnMYI/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/fdream/~4/WOoQOvq--3Y" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://fdream.net/blog/article/731.aspx/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://fdream.net/blog/article/731.aspx</feedburner:origLink></item>
		<item>
		<title>Merpressor——自动合并压缩与无缝调试</title>
		<link>http://feedproxy.google.com/~r/fdream/~3/35wVerdV0Y0/727.aspx</link>
		<comments>http://fdream.net/blog/article/727.aspx#comments</comments>
		<pubDate>Wed, 01 Jun 2011 02:13:59 +0000</pubDate>
		<dc:creator>Fdream</dc:creator>
				<category><![CDATA[Ajax Web]]></category>
		<category><![CDATA[Merpressor]]></category>
		<category><![CDATA[工具]]></category>
		<category><![CDATA[自动化]]></category>

		<guid isPermaLink="false">http://fdream.net/blog/?p=727</guid>
		<description><![CDATA[这个是在第19期WEB标准交流会上的分享PPT，分享的内容很简单，主要是大家讨论，都很诚恳地提出了各种想法和意见。在前端这一块，平常的交流太多都在于各种技术交流，而太少关注调试、测试和发布环境。 大的互联网公司可能都有各自的调试、测试和发布流程，但是在这方面的资料实在是不多。Bobby（曾在yahoo台湾，现在盛大创新院） 讲到yahoo内部其实也有这么一套，我的和他们的很类似，遗憾的是内部使用的，也无迹可寻。Hax（盛大创新院）也提到一些想法，比如自动解决依赖关系，部分更新等，都是不错的想法。 Related Posts: Merpressor —— 在线自动合并、压缩JS文件 网页即时聊天]]></description>
			<content:encoded><![CDATA[<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="425" height="355" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=10,0,0,0" align="middle"><param name="allowfullscreen" value="true" /><param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf" /><param name="wmode" value="transparent" /><param name="quality" value="high" /><param name="flashvars" value="stitle=merpressor&amp;doc=merpressor-110531204357-phpapp02&amp;show_branding=1&amp;hostedIn=iframe&amp;fullscreen_bg_color=White&amp;presentationId=8168094&amp;userName=Fdream&amp;iframe_host=&amp;totalSlides=17&amp;version_no=1306892761" /><embed id="__sse8168094" type="application/x-shockwave-flash" width="425" height="355" src="http://static.slidesharecdn.com/swf/ssplayer2.swf" flashvars="stitle=merpressor&amp;doc=merpressor-110531204357-phpapp02&amp;show_branding=1&amp;hostedIn=iframe&amp;fullscreen_bg_color=White&amp;presentationId=8168094&amp;userName=Fdream&amp;iframe_host=&amp;totalSlides=17&amp;version_no=1306892761" allowfullscreen="true" wmode="transparent" allowscriptaccess="always" quality="high" name="__sse8168094"></embed></object></p>
<p>这个是在第19期WEB标准交流会上的分享PPT，分享的内容很简单，主要是大家讨论，都很诚恳地提出了各种想法和意见。在前端这一块，平常的交流太多都在于各种技术交流，而太少关注调试、测试和发布环境。</p>
<p>大的互联网公司可能都有各自的调试、测试和发布流程，但是在这方面的资料实在是不多。Bobby（曾在yahoo台湾，现在盛大创新院） 讲到yahoo内部其实也有这么一套，我的和他们的很类似，遗憾的是内部使用的，也无迹可寻。Hax（盛大创新院）也提到一些想法，比如自动解决依赖关系，部分更新等，都是不错的想法。</p>
<p><script src="http://b.scorecardresearch.com/beacon.js?c1=7&amp;c2=7400849&amp;c3=1&amp;c4=&amp;c5=&amp;c6="></script><br />
 <script src="http://b.scorecardresearch.com/beacon.js?c1=7&amp;c2=7400849&amp;c3=1&amp;c4=&amp;c5=&amp;c6="></script></p>
<p><script src="http://b.scorecardresearch.com/beacon.js?c1=7&amp;c2=7400849&amp;c3=1&amp;c4=&amp;c5=&amp;c6="></script><br />
<h3 class='related_post_title'>Related Posts:</h3>
<ul class='related_post'>
<li><a href='http://fdream.net/blog/article/702.aspx' title='Merpressor —— 在线自动合并、压缩JS文件'>Merpressor —— 在线自动合并、压缩JS文件</a></li>
<li><a href='http://fdream.net/blog/article/379.aspx' title='网页即时聊天'>网页即时聊天</a></li>
</ul>

<p><a href="http://feedads.g.doubleclick.net/~a/DGfjNzEZKnvNkD2ewKZBsvsEXmI/0/da"><img src="http://feedads.g.doubleclick.net/~a/DGfjNzEZKnvNkD2ewKZBsvsEXmI/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/DGfjNzEZKnvNkD2ewKZBsvsEXmI/1/da"><img src="http://feedads.g.doubleclick.net/~a/DGfjNzEZKnvNkD2ewKZBsvsEXmI/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/fdream/~4/35wVerdV0Y0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://fdream.net/blog/article/727.aspx/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<media:content url="http://feedproxy.google.com/~r/fdream/~5/u1fKwtvCVuM/ssplayer2.swf" fileSize="99348" type="application/x-shockwave-flash" /><itunes:explicit>no</itunes:explicit><itunes:subtitle>这个是在第19期WEB标准交流会上的分享PPT，分享的内容很简单，主要是大家讨论，都很诚恳地提出了各种想法和意见。在前端这一块，平常的交流太多都在于各种技术交流，而太少关注调试、测试和发布环境。 大的互联网公司可能都有各自的调试、测试和发布流程，但是在这方面的资料实在是不多。Bobby（曾在yahoo台湾，现在盛大创新院） 讲到yahoo内部其实也有这么一套，我的和他们的很类似，遗憾的是内部使用的，也无迹可寻。Hax（盛大创新院）也提到一些想法，比如自动解决依赖关系，部分更新等，都是不错的想法。 Rela</itunes:subtitle><itunes:summary>这个是在第19期WEB标准交流会上的分享PPT，分享的内容很简单，主要是大家讨论，都很诚恳地提出了各种想法和意见。在前端这一块，平常的交流太多都在于各种技术交流，而太少关注调试、测试和发布环境。 大的互联网公司可能都有各自的调试、测试和发布流程，但是在这方面的资料实在是不多。Bobby（曾在yahoo台湾，现在盛大创新院） 讲到yahoo内部其实也有这么一套，我的和他们的很类似，遗憾的是内部使用的，也无迹可寻。Hax（盛大创新院）也提到一些想法，比如自动解决依赖关系，部分更新等，都是不错的想法。 Related Posts: Merpressor —— 在线自动合并、压缩JS文件 网页即时聊天</itunes:summary><itunes:keywords>Ajax Web, Merpressor, 工具, 自动化</itunes:keywords><feedburner:origLink>http://fdream.net/blog/article/727.aspx</feedburner:origLink><enclosure url="http://feedproxy.google.com/~r/fdream/~5/u1fKwtvCVuM/ssplayer2.swf" length="99348" type="application/x-shockwave-flash" /><feedburner:origEnclosureLink>http://static.slidesharecdn.com/swf/ssplayer2.swf</feedburner:origEnclosureLink></item>
		<item>
		<title>解决ubuntu下ibus没有输入窗口的问题</title>
		<link>http://feedproxy.google.com/~r/fdream/~3/IjJ8JZfpPXc/719.aspx</link>
		<comments>http://fdream.net/blog/article/719.aspx#comments</comments>
		<pubDate>Sun, 29 May 2011 03:41:53 +0000</pubDate>
		<dc:creator>Fdream</dc:creator>
				<category><![CDATA[计算机相关]]></category>
		<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[技巧]]></category>

		<guid isPermaLink="false">http://fdream.net/blog/?p=719</guid>
		<description><![CDATA[在用ubuntu 10的时候为了装google拼音输入法，把ibus给卸载了，装来scim，而且一直用google拼音也用得挺好。直到后来升级到了ubuntu 11，发现google拼音变得极不稳定，经常在选第二个词的时候挂掉，然后就再也没办法输入中文，只能重新启动scim，挺烦人的。于是考虑再次回到默认的ibus输入法，于是卸载scim，重新装上ibus，结果更悲剧的事情发生了，ibus一直提示没有输入窗口，现象就是下面的这张图。 Google了N下发现有很多人和我碰到一样的问题，但似乎都没有解决办法。折腾了几天之后，终于找到一个办法，就是修改gtk配置文件。首先进入这个目录：/usr/lib/gtk-2.0/2.10.0（gtk版本可能略有区别），里面有个gtk.immodules文件，用vim或者gedit等文本编辑器打开它，找到这两行： "/usr/lib/gtk-2.0/2.10.0/immodules/im-xim.so" "xim" "X Input Method" "gtk20" "/usr/share/locale" "ko:ja:th:zh" 把其中的xim换成ibus，然后重启一下电脑，世界就太平了： "/usr/lib/gtk-2.0/2.10.0/immodules/im-ibus.so" "ibus" "X Input Method" "gtk20" "/usr/share/locale" "ko:ja:th:zh" 重启后正常的截图： &#160; Related Posts: 其实这几天在折腾Ubuntu JavaScript类型转换太变态，慎用 让Javascript的智能提示和C#一样强悍 [转]技巧：让你的Firefox极速狂飙 用CSS轻松实现圆角]]></description>
			<content:encoded><![CDATA[<p>在用ubuntu 10的时候为了装google拼音输入法，把ibus给卸载了，装来scim，而且一直用google拼音也用得挺好。直到后来升级到了ubuntu 11，发现google拼音变得极不稳定，经常在选第二个词的时候挂掉，然后就再也没办法输入中文，只能重新启动scim，挺烦人的。于是考虑再次回到默认的ibus输入法，于是卸载scim，重新装上ibus，结果更悲剧的事情发生了，ibus一直提示没有输入窗口，现象就是下面的这张图。</p>
<p><a href="http://fdream.net/blog/wp-content/uploads/2011/05/error.gif"><img class="alignnone size-full wp-image-720" title="ibus没有输入窗口" src="http://fdream.net/blog/wp-content/uploads/2011/05/error.gif" alt="ibus没有输入窗口" width="360" height="200" /></a></p>
<p>Google了N下发现有很多人和我碰到一样的问题，但似乎都没有解决办法。折腾了几天之后，终于找到一个办法，就是修改gtk配置文件。首先进入这个目录：/usr/lib/gtk-2.0/2.10.0（gtk版本可能略有区别），里面有个gtk.immodules文件，用vim或者gedit等文本编辑器打开它，找到这两行：</p>
<pre lang="sh">"/usr/lib/gtk-2.0/2.10.0/immodules/im-xim.so"
"xim" "X Input Method" "gtk20" "/usr/share/locale" "ko:ja:th:zh"</pre>
<p>把其中的xim换成ibus，然后重启一下电脑，世界就太平了：</p>
<pre lang="sh">"/usr/lib/gtk-2.0/2.10.0/immodules/im-ibus.so"
"ibus" "X Input Method" "gtk20" "/usr/share/locale" "ko:ja:th:zh"</pre>
<p>重启后正常的截图：</p>
<p><a href="http://fdream.net/blog/wp-content/uploads/2011/05/right.gif"><img class="alignnone size-full wp-image-721" title="ibus正常" src="http://fdream.net/blog/wp-content/uploads/2011/05/right.gif" alt="ibus正常" width="360" height="200" /></a></p>
<p>&nbsp;<br />
<h3 class='related_post_title'>Related Posts:</h3>
<ul class='related_post'>
<li><a href='http://fdream.net/blog/article/639.aspx' title='其实这几天在折腾Ubuntu'>其实这几天在折腾Ubuntu</a></li>
<li><a href='http://fdream.net/blog/article/619.aspx' title='JavaScript类型转换太变态，慎用'>JavaScript类型转换太变态，慎用</a></li>
<li><a href='http://fdream.net/blog/article/549.aspx' title='让Javascript的智能提示和C#一样强悍'>让Javascript的智能提示和C#一样强悍</a></li>
<li><a href='http://fdream.net/blog/article/415.aspx' title='[转]技巧：让你的Firefox极速狂飙'>[转]技巧：让你的Firefox极速狂飙</a></li>
<li><a href='http://fdream.net/blog/article/347.aspx' title='用CSS轻松实现圆角'>用CSS轻松实现圆角</a></li>
</ul>

<p><a href="http://feedads.g.doubleclick.net/~a/QSaM4JSZZv4jy3C2G6bNI4QteI4/0/da"><img src="http://feedads.g.doubleclick.net/~a/QSaM4JSZZv4jy3C2G6bNI4QteI4/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/QSaM4JSZZv4jy3C2G6bNI4QteI4/1/da"><img src="http://feedads.g.doubleclick.net/~a/QSaM4JSZZv4jy3C2G6bNI4QteI4/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/fdream/~4/IjJ8JZfpPXc" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://fdream.net/blog/article/719.aspx/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://fdream.net/blog/article/719.aspx</feedburner:origLink></item>
		<item>
		<title>正式加入WordPress阵营</title>
		<link>http://feedproxy.google.com/~r/fdream/~3/LZgEdHcZ7is/711.aspx</link>
		<comments>http://fdream.net/blog/article/711.aspx#comments</comments>
		<pubDate>Mon, 28 Mar 2011 12:18:56 +0000</pubDate>
		<dc:creator>Fdream</dc:creator>
				<category><![CDATA[博客与我]]></category>
		<category><![CDATA[博客]]></category>
		<category><![CDATA[生活]]></category>

		<guid isPermaLink="false">http://fdream.net/blog/?p=711</guid>
		<description><![CDATA[其实想转WordPress很久了，只是苦于以前的博客程序是自己写的，需要写个转换程序，又还要重新设计制作一套皮肤，所以一直懒得去做，怕麻烦。 实在是很久不写blog了，很多次想写点什么，发现自己也已经受不了原来自己写的博客程序了，终于狠下新来研究WP的数据库，然后开始写转换程序。幸运的是这个过程没有想像的那么复杂，那么难。制作皮肤花的时间比写转换程序花的时间多太多了，新手上路总是有那么多问题的。 在blog程序转换的过程中，也顺便捣腾了一下个人页面，纯粹是无聊的小练习，用了一些简单的HTML5和CSS3，博客的皮肤也是基于此构建的，非常匆忙，甚至在IE6和IE7下都没测试过，还不知道到底如何。 先这样，边用边修改吧！如果大家有好的参考资料或者优秀的插件推荐，那就多谢了！ Related Posts: 博客已搬家，即日起改用新域名Fdream.net 冬天，很冷，很忙，很懒 冬天了，给BLOG换了个皮 修复了BLOG导航中的标签“死链” 换了个BLOG程序，给自己点动力]]></description>
			<content:encoded><![CDATA[<p>其实想转WordPress很久了，只是苦于以前的博客程序是自己写的，需要写个转换程序，又还要重新设计制作一套皮肤，所以一直懒得去做，怕麻烦。</p>
<p>实在是很久不写blog了，很多次想写点什么，发现自己也已经受不了原来自己写的博客程序了，终于狠下新来研究WP的数据库，然后开始写转换程序。幸运的是这个过程没有想像的那么复杂，那么难。制作皮肤花的时间比写转换程序花的时间多太多了，新手上路总是有那么多问题的。</p>
<p>在blog程序转换的过程中，也顺便捣腾了一下个人页面，纯粹是无聊的小练习，用了一些简单的HTML5和CSS3，博客的皮肤也是基于此构建的，非常匆忙，甚至在IE6和IE7下都没测试过，还不知道到底如何。</p>
<p>先这样，边用边修改吧！如果大家有好的参考资料或者优秀的插件推荐，那就多谢了！<br />
<h3 class='related_post_title'>Related Posts:</h3>
<ul class='related_post'>
<li><a href='http://fdream.net/blog/article/688.aspx' title='博客已搬家，即日起改用新域名Fdream.net'>博客已搬家，即日起改用新域名Fdream.net</a></li>
<li><a href='http://fdream.net/blog/article/637.aspx' title='冬天，很冷，很忙，很懒'>冬天，很冷，很忙，很懒</a></li>
<li><a href='http://fdream.net/blog/article/623.aspx' title='冬天了，给BLOG换了个皮'>冬天了，给BLOG换了个皮</a></li>
<li><a href='http://fdream.net/blog/article/595.aspx' title='修复了BLOG导航中的标签“死链”'>修复了BLOG导航中的标签“死链”</a></li>
<li><a href='http://fdream.net/blog/article/577.aspx' title='换了个BLOG程序，给自己点动力'>换了个BLOG程序，给自己点动力</a></li>
</ul>

<p><a href="http://feedads.g.doubleclick.net/~a/RNNchGDZGBiYsmGp7UEw9NijcvQ/0/da"><img src="http://feedads.g.doubleclick.net/~a/RNNchGDZGBiYsmGp7UEw9NijcvQ/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/RNNchGDZGBiYsmGp7UEw9NijcvQ/1/da"><img src="http://feedads.g.doubleclick.net/~a/RNNchGDZGBiYsmGp7UEw9NijcvQ/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/fdream/~4/LZgEdHcZ7is" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://fdream.net/blog/article/711.aspx/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		<feedburner:origLink>http://fdream.net/blog/article/711.aspx</feedburner:origLink></item>
	<media:rating>nonadult</media:rating></channel>
</rss>

