<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	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/"
	>

<channel>
	<title>Flashlight</title>
	<atom:link href="http://q.pnq.cc/feed" rel="self" type="application/rss+xml" />
	<link>http://q.pnq.cc</link>
	<description>Flash, Game, Web</description>
	<lastBuildDate>Tue, 29 Nov 2011 13:38:16 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Ubuntu下在命令行批量生成缩略图</title>
		<link>http://q.pnq.cc/archives/584</link>
		<comments>http://q.pnq.cc/archives/584#comments</comments>
		<pubDate>Tue, 29 Nov 2011 13:21:32 +0000</pubDate>
		<dc:creator>qhwa</dc:creator>
				<category><![CDATA[- linux -]]></category>
		<category><![CDATA[batch]]></category>
		<category><![CDATA[generating]]></category>
		<category><![CDATA[image]]></category>
		<category><![CDATA[imagemagick]]></category>
		<category><![CDATA[process]]></category>
		<category><![CDATA[thumbnail]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://q.pnq.cc/?p=584</guid>
		<description><![CDATA[# 准备工作：安装 imagemagick sudo apt-get install imagemagick cd /path/to/big/images #大图所在的目录 #创建小图对应的目录结构 find . -type d -print -exec mkdir '../small/{}' -p \; #批量转换! 等比例缩小到320x320之内 find . -type f -name '*.jpg' -print -exec \ convert '{}' -resize 320x320 '../small/{}' \; 这样小图都会按原先的目录结构，在上级目录的small目录出现了 其实imagemagick是一个超级神器，上面只是它很简单的一个应用&#8230;]]></description>
			<content:encoded><![CDATA[<pre class="lang-bash"><code><span class="co0"># 准备工作：安装 imagemagick</span><br />
<span class="kw2">sudo</span> <span class="kw2">apt-get</span> <span class="kw2">install</span> imagemagick<br />
<span class="kw3">cd</span> <span class="sy0">/</span>path<span class="sy0">/</span>to<span class="sy0">/</span>big<span class="sy0">/</span>images <span class="co0">#大图所在的目录</span><br />
<br />
<span class="co0">#创建小图对应的目录结构</span><br />
<span class="kw2">find</span> . <span class="re5">-type</span> d <span class="re5">-print</span> <span class="re5">-exec</span> <span class="kw2">mkdir</span> <span class="st_h">'../small/{}'</span> <span class="re5">-p</span> \;<br />
<br />
<span class="co0">#批量转换! 等比例缩小到320x320之内</span><br />
<span class="kw2">find</span> . <span class="re5">-type</span> f <span class="re5">-name</span> <span class="st_h">'*.jpg'</span> <span class="re5">-print</span> <span class="re5">-exec</span> \<br />
convert <span class="st_h">'{}'</span> <span class="re5">-resize</span> 320x320 <span class="st_h">'../small/{}'</span> \;</code></pre>

<p>这样小图都会按原先的目录结构，在上级目录的small目录出现了</p>

<p>其实<a href="http://www.imagemagick.org">imagemagick</a>是一个超级神器，上面只是它很简单的一个应用&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://q.pnq.cc/archives/584/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>让VIM与Ubuntu和睦相处</title>
		<link>http://q.pnq.cc/archives/575</link>
		<comments>http://q.pnq.cc/archives/575#comments</comments>
		<pubDate>Thu, 20 Oct 2011 06:04:29 +0000</pubDate>
		<dc:creator>qhwa</dc:creator>
				<category><![CDATA[- linux -]]></category>

		<guid isPermaLink="false">http://q.pnq.cc/?p=575</guid>
		<description><![CDATA[Vim和Ubuntu都是我的好朋友，不过他们之间好像有点不和睦。在Ubuntu11.04下gvim的菜单不能集成进全局菜单条(global menu)，而在Ubuntu11.10下gvim打开之后会非常卡。需要调解一下 解决gvim在Ubuntu 11.04中菜单显示的问题 执行gvim时，gvim的菜单不能立刻显示出来。并且报错： ** (gvim:15150): WARNING **: Unable to register window with path &#8216;/com/canonical/menu/4200024&#8242;: Timeout was reached 解决方法是运行： echo 'alias gvim=&#34;env UBUNTU_MENUPROXY=0 gvim&#34;' &#62;&#62; ~/.bashrc source ~/.bashrc 解决gvim在Ubuntu 11.10中导致电脑很卡的问题 运行： echo 'alias gvim=&#34;gvim -f&#34;' &#62;&#62; ~/.bashrc source ~/.bashrc 解决提示“pixmap”的问题 如果终端中提示： (gvim:2353): Gtk-WARNING **: 无法在模块路径中找到主题引擎：“pixmap”， 解决方法是运行： sudo apt-get install gtk2-engines-pixbuf]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.vim.org">Vim</a>和<a href="http://www.ubuntu.com">Ubuntu</a>都是我的好朋友，不过他们之间好像有点不和睦。在<a href="http://www.ubuntu.com">Ubuntu</a>11.04下gvim的菜单不能集成进全局菜单条(global menu)，而在<a href="http://www.ubuntu.com">Ubuntu</a>11.10下gvim打开之后会非常卡。需要调解一下 <img src='http://q.pnq.cc/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>

<h2>解决gvim在<a href="http://www.ubuntu.com">Ubuntu</a> 11.04中菜单显示的问题</h2>

<p>执行gvim时，gvim的菜单不能立刻显示出来。并且报错：</p>

<blockquote>
  <p>** (gvim:15150): WARNING **: Unable to register window with path &#8216;/com/canonical/menu/4200024&#8242;: Timeout was reached</p>
</blockquote>

<p>解决方法是运行：</p>

<pre class="lang-bash"><code><span class="kw3">echo</span> <span class="st_h">'alias gvim=&quot;env UBUNTU_MENUPROXY=0 gvim&quot;'</span> <span class="sy0">&gt;&gt;</span> ~<span class="sy0">/</span>.bashrc<br />
<span class="kw3">source</span> ~<span class="sy0">/</span>.bashrc</code></pre>

<hr />

<h2>解决gvim在<a href="http://www.ubuntu.com">Ubuntu</a> 11.10中导致电脑很卡的问题</h2>

<p>运行：</p>

<pre class="lang-bash"><code><span class="kw3">echo</span> <span class="st_h">'alias gvim=&quot;gvim -f&quot;'</span> <span class="sy0">&gt;&gt;</span> ~<span class="sy0">/</span>.bashrc<br />
<span class="kw3">source</span> ~<span class="sy0">/</span>.bashrc</code></pre>

<hr />

<h2>解决提示“pixmap”的问题</h2>

<p>如果终端中提示：</p>

<blockquote>
  <p>(gvim:2353): Gtk-WARNING **: 无法在模块路径中找到主题引擎：“pixmap”，</p>
</blockquote>

<p>解决方法是运行：</p>

<pre class="lang-bash"><code><span class="kw2">sudo</span> <span class="kw2">apt-get</span> <span class="kw2">install</span> gtk2-engines-pixbuf</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://q.pnq.cc/archives/575/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>自动更新git目录</title>
		<link>http://q.pnq.cc/archives/565</link>
		<comments>http://q.pnq.cc/archives/565#comments</comments>
		<pubDate>Sat, 20 Aug 2011 10:57:36 +0000</pubDate>
		<dc:creator>qhwa</dc:creator>
				<category><![CDATA[- linux -]]></category>

		<guid isPermaLink="false">http://q.pnq.cc/?p=565</guid>
		<description><![CDATA[假设我们有一批文件用Git在管理，然后在服务器上做了一个repo。团队成员先从服务器pull下来最新的版本，然后在本地修改并提交，最后push回服务器，这是很典型的应用场景。 假如现在需要服务器端收到客户端的push后，能自动更新repo目录里面的文件，听起来很简单，用钩子就可以了，不过还是遇到一些问题，好在最后在google帮助下搞定。 总结的步骤如下： 1.先在服务器端运行设置，接受提交 git config receive.denyCurrentBranch ignore 2.把以下内容保存为服务器端repo中的钩子文件（.git/hooks/post-receive） #!/bin/sh cd .. env -i git reset --hard 3.设置权限为可运行 chmod a+x post-receive 好了，这样每当服务器收到客户端的push，就会自动更新文件列表了]]></description>
			<content:encoded><![CDATA[<p>假设我们有一批文件用<a href="http://git-scm.com">Git</a>在管理，然后在服务器上做了一个repo。团队成员先从服务器pull下来最新的版本，然后在本地修改并提交，最后push回服务器，这是很典型的应用场景。</p>

<p>假如现在需要服务器端收到客户端的push后，能自动更新repo目录里面的文件，听起来很简单，用钩子就可以了，不过还是遇到一些问题，好在最后在google帮助下搞定。</p>

<p>总结的步骤如下：</p>

<p>1.先在服务器端运行设置，接受提交</p>

<pre><code>git config receive.denyCurrentBranch ignore
</code></pre>

<p>2.把以下内容保存为服务器端repo中的钩子文件（<strong>.git/hooks/post-receive</strong>）</p>

<pre class="lang-bash"><code><span class="co0">#!/bin/sh</span><br />
<span class="kw3">cd</span> ..<br />
<span class="kw2">env</span> <span class="re5">-i</span> git reset <span class="re5">--hard</span></code></pre>

<p>3.设置权限为可运行</p>

<pre><code>chmod a+x post-receive
</code></pre>

<p>好了，这样每当服务器收到客户端的push，就会自动更新文件列表了</p>
]]></content:encoded>
			<wfw:commentRss>http://q.pnq.cc/archives/565/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ubuntu下使用Array SSL VPN客户端连接VPN网络</title>
		<link>http://q.pnq.cc/archives/539</link>
		<comments>http://q.pnq.cc/archives/539#comments</comments>
		<pubDate>Fri, 01 Jul 2011 07:33:54 +0000</pubDate>
		<dc:creator>qhwa</dc:creator>
				<category><![CDATA[- linux -]]></category>
		<category><![CDATA[array]]></category>
		<category><![CDATA[ubuntu]]></category>
		<category><![CDATA[vpn]]></category>

		<guid isPermaLink="false">http://q.pnq.cc/?p=539</guid>
		<description><![CDATA[公司用的Array Networks提供的SSL VPN系统，vpn网页在Ubuntu下无法正常启动Java Applet。幸好得到了wenyue的指点，找到了方法。如果你也是Ubuntu系统，需要连接到Array SSL VPN，可以参考一下。 安装步骤 1.下载Array Networks提供的客户端程序 array_vpnc.bin sudo apt-get install libc6-i386 #64位系统也是这个包 wget http://q.pnq.cc/uploads/array_vpnc.bin chmod a+x array_vpnc.bin 2.下载这个小脚本到同个目录 #下载辅助脚本 wget http://q.pnq.cc/uploads/vpn-for-common.sh -O vpn.sh #里面会包含重要信息，我们不想别人随便访问 chmod 700 vpn.sh 3.修改vpn.sh中的配置，将vpn_host、user、key修改为你的配置 vpn_host=your_vpn_server user=your_user_name key=your_static_passwd #密码中不变的部分 使用方法： ./vpn.sh 然后根据提示输入，当看到这个提示时，就说明成功了： array_vpnc: VPN TUNNEL SUCCESSFUL! Have fun!]]></description>
			<content:encoded><![CDATA[<p>公司用的<a href="http://www.arraynetworks.com.cn/">Array Networks</a>提供的SSL VPN系统，vpn网页在Ubuntu下无法正常启动Java Applet。幸好得到了<a href="http://wenyue.me/blog/">wenyue</a>的指点，找到了方法。如果你也是Ubuntu系统，需要连接到Array SSL VPN，可以参考一下。</p>

<h2>安装步骤</h2>

<p>1.下载<a href="http://www.arraynetworks.com.cn/">Array Networks</a>提供的客户端程序 array_vpnc.bin</p>

<pre class="lang-bash"><code><span class="kw2">sudo</span> <span class="kw2">apt-get</span> <span class="kw2">install</span> libc6-i386 <span class="co0">#64位系统也是这个包</span><br />
<span class="kw2">wget</span> http:<span class="sy0">//</span>q.pnq.cc<span class="sy0">/</span>uploads<span class="sy0">/</span>array_vpnc.bin<br />
<span class="kw2">chmod</span> a+x array_vpnc.bin</code></pre>

<p>2.下载这个小脚本到同个目录</p>

<pre class="lang-bash"><code><span class="co0">#下载辅助脚本</span><br />
<span class="kw2">wget</span> http:<span class="sy0">//</span>q.pnq.cc<span class="sy0">/</span>uploads<span class="sy0">/</span>vpn-for-common.sh <span class="re5">-O</span> vpn.sh<br />
<span class="co0">#里面会包含重要信息，我们不想别人随便访问</span><br />
<span class="kw2">chmod</span> <span class="nu0">700</span> vpn.sh</code></pre>

<p>3.修改vpn.sh中的配置，将vpn_host、user、key修改为你的配置</p>

<pre class="lang-bash"><code><span class="re2">vpn_host</span>=your_vpn_server<br />
<span class="re2">user</span>=your_user_name<br />
<span class="re2">key</span>=your_static_passwd <span class="co0">#密码中不变的部分</span></code></pre>

<h2>使用方法：</h2>

<pre class="lang-bash"><code>.<span class="sy0">/</span>vpn.sh</code></pre>

<p>然后根据提示输入，当看到这个提示时，就说明成功了：</p>

<blockquote>
  <p>array_vpnc: VPN TUNNEL SUCCESSFUL!</p>
</blockquote>

<p>Have fun!</p>
]]></content:encoded>
			<wfw:commentRss>http://q.pnq.cc/archives/539/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Flash真的适合做网站应用吗？</title>
		<link>http://q.pnq.cc/archives/496</link>
		<comments>http://q.pnq.cc/archives/496#comments</comments>
		<pubDate>Thu, 31 Mar 2011 14:24:27 +0000</pubDate>
		<dc:creator>qhwa</dc:creator>
				<category><![CDATA[- Flash -]]></category>
		<category><![CDATA[bug]]></category>
		<category><![CDATA[cookie]]></category>
		<category><![CDATA[flash]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[性能]]></category>
		<category><![CDATA[问题]]></category>

		<guid isPermaLink="false">http://q.pnq.cc/?p=496</guid>
		<description><![CDATA[两年前，我们开发了一套基于Flash的文件（主要是图片）上传RIA应用，提供给阿里巴巴的用户使用。如果你使用过Wordpress或flickr上传图片，你应该已经用过类似的产品。这个程序基于YUI Uploader开发，增加了一个实用的功能——在客户端先将图片缩小，再上传到服务器。用户用数码相机拍摄的照片往往有600万以上的像素，但产品图片放到阿里巴巴网站上显示，并不需要这么大的像素，通常等比例缩小到1024×1024之内就可以了。借助于Flash对图片先缩小再上传的技术，我们在没有增加服务器投入的情况下，将原先上传图片的尺寸限制由250KB/张提升到了5MB/张。同时，Flash上传还比传统HTML表单方式上传有更好的体验，例如可以多选一批文件同时上传、可以实时展示上传进度、选择文件时可以过滤非图片文件。 这个组件获得了很大的成功。上线后不久，阿里巴巴网站上用户的图片上传数量由日均1万张左右上升至日均15万张左右。但在这个上传应用投入应用的两年中，我们遇到了各种问题。 1. bug 在基于IE多标签浏览器中的伪沙箱问题就不说了，最严重的是cookie的问题。使用FileReference.upload的方式上传文件，http请求中附带的cookie信息不一定是当前浏览器进程的cookie，在Firefox、chrome等非IE浏览器中非常严重，可能传输的是IE中的cookie。即便是IE，也可能传输的cookie内容和当前页面的cookie记录不符合。这直接导致服务器端在收到文件之后的安全验证中失败。而对于阿里巴巴这样的大型网站，有比较成熟的java web框架，要去掉对cookie的依赖非常麻烦。于是结果就是，首先我们只有在用户使用IE系浏览器的时候才使用Flash上传，其次我们隔三岔五的还会收到使用IE的某些客户的投诉，在花费了大量的时间排查之后，我发现是由于cookie的问题导致上传失败。这个bug已经存在很多年，但是随着Flash从9升级到10，许多版本过去了，问题依然没有被解决。对于闭源的Flash，我们也帮不上忙。 2.性能 相对于现今数码相机的像素量，5MB的大小限制非常保守。但大于5M的时候，在一些低配置的电脑上，读取文件内容的时候就会发生浏览器假死现象。假死很容易导致浏览器崩溃，所以我们采取了保守的限制——5MB。 另外一个性能消耗是将BitmapData编码成JPEG文件的时候。Adobe提供了JPEGEncoder，但由于是Array实现的，所以性能是个问题。编码一个2880×2880的图片在一台中等配置的电脑上大约需要15秒时间。 我用Vector改写了这个类，时间缩短为3.5秒左右。使用Alchemy，时间进一步缩短到1.5秒左右。但还是不够安全，所以最后采用了异步Vector的方式，延长编码的时间，以保证程序的稳定性。（评测在这里） 3.图片质量 Flash内置的最好的图片缩小算法（用BitmapData.draw，并将smoothing参数设为true），在缩小图片的时候容易产生锯齿。因此我改写了Jacwright提供的缩小算法，图片质量的问题解决，但代价是性能又降低了一些。 4.安全限制 Flash10.0之后，增加了一个安全限制——当URLLoader以标准文件上传的方式发送POST请求的时候，需要由用户的UI操作（鼠标点击或按键事件）触发。因为我们对用户的图片做了处理，已经无法再通过FileReference上传，只能通过URLLoader。这个安全性限制规定每次发起一个上传文件的URLLoader请求，都必须让用户点击一下鼠标才可以。如果用户选择了20张图片，就要点击20次鼠标。这显然是无法接受的。因此我们放弃了用标准文件上传，采用普通post形式。代价是失去了对上传进度的跟踪，不知道文件上传的百分比；同时服务器端也需要改造。 改变 最近，我们做了一个决定：开发一个类似功能的ActiveX控件，替代Flash作为图片上传的主要解决方案。ActiveX的优势是性能，不足之处在于只能在Windows+IE浏览器中使用，但实际上我们的Flash上传目前也只能在IE中使用。Flash真的适合像阿里巴巴这样的网站使用吗？闭源和性能是Flash最大的问题。但在HTML5被广泛支持前，Flash和传统Ajax还是我们最主要的富客户端应用开发技术，相对于ActiveX、Silverlight、JavaFX、Gear等技术来说，Flash还是有安装率优势的。我们看到Adobe最近在新功能开发方面非常给力，值得称赞，但基础的功能的持续完善对开发者也同样重要。目前Flash依然是我们很重要的RIA技术，但是HTML5完全到来的那一天，现在很难说。]]></description>
			<content:encoded><![CDATA[<p>两年前，我们开发了一套基于Flash的文件（主要是图片）上传RIA应用，提供给阿里巴巴的用户使用。如果你使用过Wordpress或flickr上传图片，你应该已经用过类似的产品。这个程序基于<a title="YUI Uploader" href="http://developer.yahoo.com/yui/uploader/">YUI Uploader</a>开发，增加了一个实用的功能——在客户端先将图片缩小，再上传到服务器。用户用数码相机拍摄的照片往往有600万以上的像素，但产品图片放到阿里巴巴网站上显示，并不需要这么大的像素，通常等比例缩小到1024×1024之内就可以了。借助于Flash对图片先缩小再上传的技术，我们在没有增加服务器投入的情况下，将原先上传图片的尺寸限制由250KB/张提升到了5MB/张。同时，Flash上传还比传统HTML表单方式上传有更好的体验，例如可以多选一批文件同时上传、可以实时展示上传进度、选择文件时可以过滤非图片文件。</p>

<p><img class="alignnone size-full wp-image-512" style="margin: 5px; border: 1px solid black;" title="Screenshot" src="http://q.pnq.cc/wp-content/uploads/2011/03/Screenshot.png" alt="" width="782" height="352" /></p>

<p>这个组件获得了很大的成功。上线后不久，阿里巴巴网站上用户的图片上传数量由日均1万张左右上升至日均15万张左右。但在这个上传应用投入应用的两年中，我们遇到了各种问题。</p>

<h2>1. bug</h2>

<p><img class="alignnone size-medium wp-image-508" title="man062" src="http://q.pnq.cc/wp-content/uploads/2011/03/man062-500x494.jpg" alt="" width="500" height="494" /></p>

<p>在<a title="Flash在某些多标签浏览器中的“伪沙箱”问题" href="http://q.pnq.cc/archives/443">基于IE多标签浏览器中的伪沙箱问题</a>就不说了，最严重的是cookie的问题。使用FileReference.upload的方式上传文件，http请求中附带的cookie信息不一定是当前浏览器进程的cookie，在Firefox、chrome等非IE浏览器中非常严重，可能传输的是IE中的cookie。即便是IE，也可能传输的cookie内容和当前页面的cookie记录不符合。这直接导致服务器端在收到文件之后的安全验证中失败。而对于阿里巴巴这样的大型网站，有比较成熟的java web框架，要去掉对cookie的依赖非常麻烦。于是结果就是，首先我们只有在用户使用IE系浏览器的时候才使用Flash上传，其次我们隔三岔五的还会收到使用IE的某些客户的投诉，在花费了大量的时间排查之后，我发现是由于cookie的问题导致上传失败。<a href="http://cookbooks.adobe.com/post_Why_is_session_info__cookies__not_sent_when_upload-12029.html">这个bug</a>已经存在很多年，但是随着Flash从9升级到10，许多版本过去了，问题依然没有被解决。对于闭源的Flash，我们也帮不上忙。</p>

<h2>2.性能</h2>

<p><img class="alignnone size-medium wp-image-498" title="Mignight_Run_by_Orikon" src="http://q.pnq.cc/wp-content/uploads/2011/03/Mignight_Run_by_Orikon-500x340.jpg" alt="" width="500" height="340" /></p>

<p>相对于现今数码相机的像素量，5MB的大小限制非常保守。但大于5M的时候，在一些低配置的电脑上，读取文件内容的时候就会发生浏览器假死现象。假死很容易导致浏览器崩溃，所以我们采取了保守的限制——5MB。</p>

<p>另外一个性能消耗是将BitmapData编码成JPEG文件的时候。Adobe提供了JPEGEncoder，但由于是Array实现的，所以性能是个问题。编码一个2880×2880的图片在一台中等配置的电脑上大约需要15秒时间。</p>

<p>我用Vector改写了这个类，时间缩短为3.5秒左右。使用Alchemy，时间进一步缩短到1.5秒左右。但还是不够安全，所以最后采用了异步Vector的方式，延长编码的时间，以保证程序的稳定性。（评测在<a title="异步+Vector版本的JPEG编码器" href="http://q.pnq.cc/archives/307">这里</a>）</p>

<h2>3.图片质量</h2>

<p><img class="alignnone size-medium wp-image-505" title="iblrst00076625" src="http://q.pnq.cc/wp-content/uploads/2011/03/iblrst00076625-500x332.jpg" alt="" width="500" height="332" /></p>

<p>Flash内置的最好的图片缩小算法（用BitmapData.draw，并将smoothing参数设为true），在缩小图片的时候容易产生锯齿。因此我改写了<a href="http://jacwright.com/">Jacwright</a>提供的<a href="http://code.google.com/p/jacwright/source/browse/trunk/flash/jac/src/jac/image/ImageUtils.as">缩小算法</a>，图片质量的问题解决，但代价是性能又降低了一些。</p>

<h2>4.安全限制</h2>

<p><img class="alignnone size-medium wp-image-511" title="rad600-02833372s" src="http://q.pnq.cc/wp-content/uploads/2011/03/rad600-02833372s-500x333.jpg" alt="" width="500" height="333" /></p>

<p>Flash10.0之后，增加了一个安全限制——当URLLoader以标准文件上传的方式发送POST请求的时候，需要由用户的UI操作（鼠标点击或按键事件）触发。因为我们对用户的图片做了处理，已经无法再通过FileReference上传，只能通过URLLoader。这个安全性限制规定每次发起一个上传文件的URLLoader请求，都必须让用户点击一下鼠标才可以。如果用户选择了20张图片，就要点击20次鼠标。这显然是无法接受的。因此我们放弃了用标准文件上传，采用普通post形式。代价是失去了对上传进度的跟踪，不知道文件上传的百分比；同时服务器端也需要改造。</p>

<h2>改变</h2>

<p>最近，我们做了一个决定：开发一个类似功能的ActiveX控件，替代Flash作为图片上传的主要解决方案。ActiveX的优势是性能，不足之处在于只能在Windows+IE浏览器中使用，但实际上我们的Flash上传目前也只能在IE中使用。Flash真的适合像阿里巴巴这样的网站使用吗？闭源和性能是Flash最大的问题。但在HTML5被广泛支持前，Flash和传统Ajax还是我们最主要的富客户端应用开发技术，相对于ActiveX、Silverlight、JavaFX、Gear等技术来说，Flash还是有安装率优势的。我们看到Adobe最近在新功能开发方面非常给力，值得称赞，但基础的功能的持续完善对开发者也同样重要。目前Flash依然是我们很重要的RIA技术，但是HTML5完全到来的那一天，现在很难说。</p>
]]></content:encoded>
			<wfw:commentRss>http://q.pnq.cc/archives/496/feed</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>如何一键启动Virtualbox虚拟机</title>
		<link>http://q.pnq.cc/archives/489</link>
		<comments>http://q.pnq.cc/archives/489#comments</comments>
		<pubDate>Fri, 25 Mar 2011 01:57:54 +0000</pubDate>
		<dc:creator>qhwa</dc:creator>
				<category><![CDATA[- linux -]]></category>
		<category><![CDATA[virtualbox]]></category>

		<guid isPermaLink="false">http://q.pnq.cc/?p=489</guid>
		<description><![CDATA[现在用Ubuntu或者Mac的人越来越多了，但很多情况下还是离不开Windows，所以大多数人都是安装了Virtualbox，在VBox里面运行Windows虚拟机。 你是怎样启动Windows虚拟机的呢？是不是 1. 运行Virtualbox 2. 点选虚拟机的图标 3.点“启动” 那么可以考虑一下给单个虚拟机创建快捷方式，提高工作效率。别小看这点时间哦，每天节约下来的时间不可小视呢！ 在桌面/Dock上创建一个程序快捷方式: /usr/bin/VBoxManage startvm 虚拟机名称 例如我的虚拟机叫做XP，那么这个命令就是 /usr/bin/VBoxManage startvm XP 不同的系统可能VBoxManage所在的地方不一样，用这个命令查找VBoxManage所在路径： which VBoxManage 至于怎么创建快捷方式，可以参考网上的教程。这是我的Ubuntu上的效果： ps. 图标是在iconfinder找到的 &#160;]]></description>
			<content:encoded><![CDATA[<p><img class="alignnone size-full wp-image-491" title="Screenshot-2" src="http://q.pnq.cc/wp-content/uploads/2011/03/Screenshot-2.jpg" alt="" width="865" height="136" />
现在用Ubuntu或者Mac的人越来越多了，但很多情况下还是离不开Windows，所以大多数人都是安装了Virtualbox，在VBox里面运行Windows虚拟机。</p>

<p>你是怎样启动Windows虚拟机的呢？是不是
1. 运行Virtualbox 2. 点选虚拟机的图标 3.点“启动”</p>

<p>那么可以考虑一下给单个虚拟机创建快捷方式，提高工作效率。别小看这点时间哦，每天节约下来的时间不可小视呢！</p>

<p>在桌面/Dock上创建一个程序快捷方式:
<code>/usr/bin/VBoxManage startvm 虚拟机名称</code></p>

<p>例如我的虚拟机叫做XP，那么这个命令就是
<code>/usr/bin/VBoxManage startvm XP</code></p>

<p>不同的系统可能VBoxManage所在的地方不一样，用这个命令查找VBoxManage所在路径：
<code>which VBoxManage</code></p>

<p>至于怎么创建快捷方式，可以参考网上的教程。这是我的Ubuntu上的效果：</p>

<p><img class="alignnone size-full wp-image-490" title="Virtualbox shortcut" src="http://q.pnq.cc/wp-content/uploads/2011/03/Screenshot-3.jpg" alt="" width="865" height="725" /></p>

<p>ps. 图标是在<a href="http://www.iconfinder.net" target="_blank">iconfinder</a>找到的</p>

<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://q.pnq.cc/archives/489/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>crontab无效的原因分析</title>
		<link>http://q.pnq.cc/archives/480</link>
		<comments>http://q.pnq.cc/archives/480#comments</comments>
		<pubDate>Thu, 24 Mar 2011 13:11:11 +0000</pubDate>
		<dc:creator>qhwa</dc:creator>
				<category><![CDATA[- linux -]]></category>
		<category><![CDATA[crontab]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[shell]]></category>

		<guid isPermaLink="false">http://q.pnq.cc/?p=480</guid>
		<description><![CDATA[有时候会发生这样的现象，命令是可以在shell中正常运行的，但添加到crontab中定时运行的时候，就发生一些异常的事情。（如果还不知道 Crontab 是什么的话，可以看一下这里先） 比如我今天在目录/home/ued66/asproj-builder 下写了一个 build-all.sh: svn up #更新代码 ./compile.rb --all &#62;&#62; ./log/run.log #编译，并将结果记录 在shell中运行这个命令是正常的： /home/ued66/asproj-builder/build-all.sh crontab中这样写： */5 * * * * /home/ued66/asproj-builder/build-all.sh (为了测试方便，设成每5分钟运行一次，实际是每天运行一次足矣） 虽然是同个命令，但是compile.rb却没有被正确调用。 经过调试，发现问题有两个： 1. 路径问题 既然用了相对路径，必须要把当前目录设置正确。把crontab写成这样： */5 * * * * cd /home/ued66/asproj-builder &#38;&#38; ./build-all.sh 2. 环境问题 compile.rb 是用ruby写的一个脚本，而我的ruby程序是用源码编译安装的，安装目录是/usr/local/ruby。compile.rb的第一行是 #!/usr/bin/env ruby 这是告诉shell使用ruby来执行这个脚本。但问题在于crontab运行的时候是没有加载用户环境变量的，“which ruby“运行结果为空也验证了这点。所以compile.rb不能被正确执行也很好理解了。 最后把build-all.sh写成这样，问题解决： #!/bin/sh svn up /usr/local/ruby/bin/ruby compile.rb --all &#62;&#62; ./log/run.log 看着程序自动运作起来，非常开心啊！]]></description>
			<content:encoded><![CDATA[<p>有时候会发生这样的现象，命令是可以在shell中正常运行的，但添加到crontab中定时运行的时候，就发生一些异常的事情。（如果还不知道 <a href="http://baike.baidu.com/view/1229061.html?fromTaglist">Crontab</a> 是什么的话，可以看一下<a href="http://baike.baidu.com/view/1229061.html?fromTaglist">这里</a>先）</p>

<p>比如我今天在目录/home/ued66/asproj-builder 下写了一个<em> build-all.sh</em>:
<code>svn up <span style="color: #888888;">#更新代码</span>
./compile.rb --all &gt;&gt; ./log/run.log <span style="color: #999999;">#编译，并将结果记录</span></code></p>

<p>在shell中运行这个命令是正常的：
<code>/home/ued66/asproj-builder/build-all.sh</code></p>

<p>crontab中这样写：
<code>*/5 * * * * /home/ued66/asproj-builder/build-all.sh</code>
(为了测试方便，设成每5分钟运行一次，实际是每天运行一次足矣）</p>

<p>虽然是同个命令，但是compile.rb却没有被正确调用。</p>

<p>经过调试，发现问题有两个：</p>

<p><strong>1. 路径问题</strong>
既然用了相对路径，必须要把当前目录设置正确。把crontab写成这样：
<code>*/5 * * * * cd /home/ued66/asproj-builder &amp;&amp; ./build-all.sh</code></p>

<p><strong>2. 环境问题</strong>
compile.rb 是用ruby写的一个脚本，而我的ruby程序是用源码编译安装的，安装目录是/usr/local/ruby。compile.rb的第一行是
<span style="color: #ff0000;"><code>#!/usr/bin/env ruby</code></span>
这是告诉shell使用ruby来执行这个脚本。但问题在于crontab运行的时候是没有加载用户环境变量的，“which ruby“运行结果为空也验证了这点。所以compile.rb不能被正确执行也很好理解了。</p>

<p>最后把build-all.sh写成这样，问题解决：
<code><span style="color: #999999;">#!/bin/sh</span>
svn up
<span style="color: #ff0000;"><strong>/usr/local/ruby/bin/ruby</strong></span> compile.rb --all &gt;&gt; ./log/run.log</code></p>

<p>看着程序自动运作起来，非常开心啊！</p>
]]></content:encoded>
			<wfw:commentRss>http://q.pnq.cc/archives/480/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Virtualbox 网络桥接不起作用？试试装增强功能</title>
		<link>http://q.pnq.cc/archives/474</link>
		<comments>http://q.pnq.cc/archives/474#comments</comments>
		<pubDate>Fri, 18 Mar 2011 13:47:07 +0000</pubDate>
		<dc:creator>qhwa</dc:creator>
				<category><![CDATA[- Misc：其他 -]]></category>

		<guid isPermaLink="false">http://q.pnq.cc/?p=474</guid>
		<description><![CDATA[今天晚上在Ubuntu的服务器上用Virtualbox安装了一个Windows 7的虚拟机，一切都好，但在网络配置的时候遇到了问题。网卡选择桥接（Bridge）模式，运行时能（从DHCP服务器）得到ip地址，却无法上网。外部的计算机也访问不了该ip。 Google之，尝试了很多方法，都没有效果。 最后偶然发现，安装完增强功能包之后，居然桥接模式就正常了。进一步证明，这个增强功能包是必备的东东。 安装增强功能包，一开始是从Virtualbox菜单中安装，发现下载速度太慢。在apt里面搜到原来有个包：virtualbox-guest-additions，所以先执行这句： sudo apt-get install virtualbox-guest-additions 然后再到VB虚拟机里面点安装增强功能，可以节约一点时间。]]></description>
			<content:encoded><![CDATA[<p>今天晚上在Ubuntu的服务器上用Virtualbox安装了一个Windows 7的虚拟机，一切都好，但在网络配置的时候遇到了问题。网卡选择桥接（Bridge）模式，运行时能（从DHCP服务器）得到ip地址，却无法上网。外部的计算机也访问不了该ip。</p>

<p>Google之，尝试了很多方法，都没有效果。</p>

<p>最后偶然发现，安装完增强功能包之后，居然桥接模式就正常了。进一步证明，这个增强功能包是必备的东东。</p>

<p>安装增强功能包，一开始是从Virtualbox菜单中安装，发现下载速度太慢。在apt里面搜到原来有个包：virtualbox-guest-additions，所以先执行这句：
<code>sudo apt-get install virtualbox-guest-additions</code></p>

<p>然后再到VB虚拟机里面点安装增强功能，可以节约一点时间。</p>
]]></content:encoded>
			<wfw:commentRss>http://q.pnq.cc/archives/474/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Flash在某些多标签浏览器中的“伪沙箱”问题</title>
		<link>http://q.pnq.cc/archives/443</link>
		<comments>http://q.pnq.cc/archives/443#comments</comments>
		<pubDate>Sat, 30 Oct 2010 14:31:02 +0000</pubDate>
		<dc:creator>qhwa</dc:creator>
				<category><![CDATA[- Flash -]]></category>
		<category><![CDATA[360]]></category>
		<category><![CDATA[crossdomain]]></category>
		<category><![CDATA[flash]]></category>
		<category><![CDATA[maxthon]]></category>
		<category><![CDATA[sandbox]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[Tab]]></category>
		<category><![CDATA[Tecent Traver]]></category>
		<category><![CDATA[安全]]></category>
		<category><![CDATA[沙箱]]></category>

		<guid isPermaLink="false">http://q.pnq.cc/archives/443</guid>
		<description><![CDATA[在Flash播放器运行时，将不同来源的资源划分到独立的沙箱(sandbox)内，不同沙箱之间不能彼此操作数据（除非目标沙箱做过一些设置，授权其他沙箱可访问），这就是Flash的跨沙箱问题。当Flash文件(.swf) 和页面(.html)不在同一个域名下时，如果不经过Flash内部声明System.allowDomain，html无法访问flash定义的接口；不经过html设置allowScriptAccess为&#8217;always&#8217;，Flash也无法调用页面上的js函数。 那么如果html和flash都设置了互相可以访问，是否Flash和html之间就可以互相访问了呢？理论上是的，然而实际上却不是。 在Chrome、Firefox等非IE浏览器上，是没有问题的。在“纯正”的IE6、IE7、IE8上也是正常的。但是在傲游、360浏览器、腾讯浏览器等基于IE的多标签浏览器中，刷新页面的时候，Flash播放器还是会抛安全沙箱错误。 点击访问测试页面。 使用上面说的“基于IE的多标签浏览器”访问，你会看到，第一次是正常的，刷新之后就不正常。如果你安装的是debug版本的播放器，可以看到Flash运行时发生了异常。 SecurityError: Error #2060: 安全沙箱冲突:ExternalInterface 调用者 http://pnq.cc/temp/test-dmm-crssdmn.swf 不能访问 http://q.pnq.cc/works/test/test-dmm-crssmn.html。&#160;&#160;&#160; at flash.external::ExternalInterface$/_initJS()&#160;&#160;&#160; at flash.external::ExternalInterface$/call()&#160;&#160;&#160; at Main/start()&#160;&#160;&#160; at Main/init()&#160;&#160;&#160; at Main() Flash的源码： package &#123; &#160; &#160; import flash.display.Sprite; &#160; &#160; import flash.external.ExternalInterface; &#160; &#160; import flash.system.Security; &#160; &#160; import flash.text.TextField; &#160; &#160; /** &#160; &#160; &#160;* Flash缓存造成的伪沙箱问题演示 &#160; &#160; &#160;* @author qhwa [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://q.pnq.cc/wp-content/uploads/2010/10/sandbox.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="sandbox" border="0" alt="sandbox" src="http://q.pnq.cc/wp-content/uploads/2010/10/sandbox_thumb.png" width="479" height="367"></a></p>

<p>在Flash播放器运行时，将不同来源的资源划分到独立的沙箱(sandbox)内，不同沙箱之间不能彼此操作数据（除非目标沙箱做过一些设置，授权其他沙箱可访问），这就是Flash的跨沙箱问题。当Flash文件(.swf) 和页面(.html)不在同一个域名下时，如果不经过Flash内部声明System.allowDomain，html无法访问flash定义的接口；不经过html设置allowScriptAccess为&#8217;always&#8217;，Flash也无法调用页面上的js函数。</p>

<p>那么如果html和flash都设置了互相可以访问，是否Flash和html之间就可以互相访问了呢？理论上是的，然而实际上却不是。<img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-brokenheart" alt="破碎的心" src="http://q.pnq.cc/wp-content/uploads/2010/10/wlEmoticon-brokenheart.png"></p>

<p><span id="more-443"></span></p>

<p>在Chrome、Firefox等非IE浏览器上，是没有问题的。在“纯正”的IE6、IE7、IE8上也是正常的。但是在傲游、360浏览器、腾讯浏览器等<strong><font color="#ff0000" size="4">基于IE的多标签浏览器</font></strong>中，<strong>刷新</strong>页面的时候，Flash播放器还是会抛安全沙箱错误。</p>

<p><a href="http://q.pnq.cc/works/test/test-dmm-crssmn.html" target="_blank">点击访问测试页面</a>。</p>

<p>使用上面说的“基于IE的多标签浏览器”访问，你会看到，第一次是正常的，刷新之后就不正常。如果你安装的是debug版本的播放器，可以看到Flash运行时发生了异常。</p>

<blockquote> <p>SecurityError: Error #2060: <strong>安全沙箱冲突</strong>:ExternalInterface 调用者 <a href="http://pnq.cc/temp/test-dmm-crssdmn.swf">http://pnq.cc/temp/test-dmm-crssdmn.swf</a> 不能访问 <a href="http://q.pnq.cc/works/test/test-dmm-crssmn.html。">http://q.pnq.cc/works/test/test-dmm-crssmn.html。</a><br />&nbsp;&nbsp;&nbsp; at flash.external::ExternalInterface$/_initJS()<br />&nbsp;&nbsp;&nbsp; at flash.external::ExternalInterface$/call()<br />&nbsp;&nbsp;&nbsp; at Main/start()<br />&nbsp;&nbsp;&nbsp; at Main/init()<br />&nbsp;&nbsp;&nbsp; at Main()</p></blockquote>

<p>Flash的源码：</p>

<pre class="lang-actionscript"><code>package <br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw3">import</span> flash.<span class="me1">display</span>.<span class="me1">Sprite</span>;<br />
&nbsp; &nbsp; <span class="kw3">import</span> flash.<span class="me1">external</span>.<span class="me1">ExternalInterface</span>;<br />
&nbsp; &nbsp; <span class="kw3">import</span> flash.<span class="kw3">system</span>.<span class="me1">Security</span>;<br />
&nbsp; &nbsp; <span class="kw3">import</span> flash.<span class="kw3">text</span>.<span class="kw3">TextField</span>;<br />
<br />
&nbsp; &nbsp; <span class="coMULTI">/**<br />
&nbsp; &nbsp; &nbsp;* Flash缓存造成的伪沙箱问题演示<br />
&nbsp; &nbsp; &nbsp;* @author qhwa<br />
&nbsp; &nbsp; &nbsp;*/</span><br />
&nbsp; &nbsp; <span class="kw3">public</span> <span class="kw2">class</span> Main <span class="kw3">extends</span> Sprite <br />
&nbsp; &nbsp; <span class="br0">&#123;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">public</span> <span class="kw2">function</span> Main<span class="br0">&#40;</span><span class="br0">&#41;</span>:<span class="kw3">void</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span> &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> tf:<span class="kw3">TextField</span> = <span class="kw2">new</span> <span class="kw3">TextField</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; tf.<span class="kw3">text</span> = <span class="st0">'flash ready'</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; tf.<span class="kw3">autoSize</span> = <span class="st0">'left'</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; addChild<span class="br0">&#40;</span>tf<span class="br0">&#41;</span>;<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">//允许被所有其他沙箱中的js或flash调用</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Security.<span class="kw3">allowDomain</span><span class="br0">&#40;</span><span class="st0">&quot;*&quot;</span><span class="br0">&#41;</span>;<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">start</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">private</span> <span class="kw2">function</span> <span class="kw3">start</span><span class="br0">&#40;</span><span class="br0">&#41;</span>:<span class="kw3">void</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">//在基于IE的多标签浏览器中，这里运行时可能出错</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ExternalInterface.<span class="kw3">call</span><span class="br0">&#40;</span><span class="st0">&quot;alert&quot;</span>, <span class="st0">&quot;Hi, flash is ready!&quot;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ExternalInterface.<span class="me1">addCallback</span><span class="br0">&#40;</span><span class="st0">'drawCircle'</span>, drawCircle<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">private</span> <span class="kw2">function</span> drawCircle<span class="br0">&#40;</span><span class="br0">&#41;</span>:<span class="kw3">void</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">TextField</span><span class="br0">&#40;</span>getChildAt<span class="br0">&#40;</span><span class="nu0">0</span><span class="br0">&#41;</span><span class="br0">&#41;</span>.<span class="me1">appendText</span><span class="br0">&#40;</span><span class="st0">'nDraw a circle'</span><span class="br0">&#41;</span>;<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; graphics.<span class="kw3">beginFill</span><span class="br0">&#40;</span><span class="kw3">Math</span>.<span class="kw3">random</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="sy0">*</span> 0xFFFFFF, .5<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; graphics.<span class="me1">drawCircle</span><span class="br0">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">Math</span>.<span class="kw3">random</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="sy0">*</span> <span class="kw3">stage</span>.<span class="me1">stageWidth</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">Math</span>.<span class="kw3">random</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="sy0">*</span> <span class="kw3">stage</span>.<span class="me1">stageHeight</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="nu0">50</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; graphics.<span class="kw3">endFill</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
<br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<br />
<span class="br0">&#125;</span></code></pre>

<p>似乎一旦swf是从缓存中读取的，allowScriptAccess这个配置就不起作用？为了验证是不是缓存引起的，我们每次为swf文件地址后面加上随机的数字，发现就不存在上面的问题了。可见这个问题确实是<strong>浏览器缓存造成</strong>的。</p>

<p>为swf文件动态加时间戳或随机数，通过防止缓存可以回避掉这个问题。不过这不是一个很好的方案，因为这会极大增加服务器的压力，并且导致页面加载速度一直都很慢。</p>

<p>不过好消息是，目前有个比这个更好的方案：<strong>延迟Flash的初始化功能</strong>。通过将Flash的ExternalInterface.addCallback时机延后一些，就可以解决这个问题。</p>

<p>修改一下Flash的代码，加一个setTimeout：</p>

<pre class="lang-actionscript"><code>...<span class="br0">&#40;</span>略<span class="br0">&#41;</span><br />
<br />
<span class="kw3">public</span> <span class="kw2">class</span> Main <span class="kw3">extends</span> Sprite <br />
<span class="br0">&#123;</span><br />
<br />
&nbsp; &nbsp; <span class="kw3">public</span> <span class="kw2">function</span> Main<span class="br0">&#40;</span><span class="br0">&#41;</span>:<span class="kw3">void</span> <br />
&nbsp; &nbsp; <span class="br0">&#123;</span> &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; ...<span class="br0">&#40;</span>略<span class="br0">&#41;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">//start();</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; setTimeout<span class="br0">&#40;</span><span class="kw3">start</span>, <span class="nu0">500</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<br />
&nbsp; &nbsp; ...<span class="br0">&#40;</span>略<span class="br0">&#41;</span><br />
<br />
<span class="br0">&#125;</span></code></pre>

<p><a href="http://q.pnq.cc/works/test/test-dmm-crssmn-edited.html" target="_blank">测试修改后的效果</a></p>

<p>那么，延迟多少比较合适呢？如果太多，用户会感觉到明显的延迟；太少，一些性能较差的电脑上问题依然存在。根据我一年多总结的经验，<font color="#ff0000">500ms</font>是比较合理的数字。目前阿里巴巴中国网站上使用的Flash应用程序，如果有需要和js通信，都是延迟500ms初始化。</p>

<p>顺便说一下，延迟500ms还有另外的一个作用。IE6中，Flash初始化的时候无法得到 stage.stageWidth正确的数字，返回是0（stageHeight也一样）。延迟一点初始化就可以得到正确的数值了。</p>

<p>目前我还没有发现比延迟初始化更好的解决方案，如果你有更好的办法，欢迎交流！</p>
]]></content:encoded>
			<wfw:commentRss>http://q.pnq.cc/archives/443/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>使用Fiddler提高前端工作效率 (实例篇)</title>
		<link>http://q.pnq.cc/archives/422</link>
		<comments>http://q.pnq.cc/archives/422#comments</comments>
		<pubDate>Sun, 25 Apr 2010 08:19:06 +0000</pubDate>
		<dc:creator>qhwa</dc:creator>
				<category><![CDATA[- Misc：其他 -]]></category>
		<category><![CDATA[debugger]]></category>
		<category><![CDATA[fiddler]]></category>
		<category><![CDATA[tools]]></category>
		<category><![CDATA[前端]]></category>
		<category><![CDATA[调试]]></category>

		<guid isPermaLink="false">http://q.pnq.cc/?p=422</guid>
		<description><![CDATA[在上一篇（介绍篇）中，我们对Fiddler Web Debugger有了简单的接触，也许你已经开始在用Fiddler进行HTTP相关的调试，在这一篇，我们将通过一个实例了解Fiddler的神奇魔法。 在我们前端开发的日常工作中，发现服务器上某个css/javascript文件有问题，需要修改，那真是家常便饭。通常，我们需要将文件进行修改，然后重新发布再验证，这样就很容易影响到生产环境的稳定性。更普遍的做法是，我们在开发环境中修改文件并验证，然后发布到生产环境。虽然安全，却比较繁琐。而利用Fiddler的可以修改HTTP数据的特性，我们就非常敏捷地基于生产环境“修改——验证——发布”。 假设我们发现这个页面有问题，需要修改所引用的js文件（http://www.aliued.cn/wp-includes/js/comment-reply.js?ver=20090102）。 第一步：用Fiddler查看页面的数据流列表，找到这个js文件的session tip: 最好是没有缓存的返回内容（Result Code是200），这样可以进行下一步的保存。不是200也没关系，你只要本地硬盘上有这个文件就好了。 第二步：将js文件保存到本地（如果本地已经有这个文件，可以跳过这步） 在这个js session上右键点击，选择“Save – Response –Response Body…”，将js文件的内容保存到本地。记住存的位置，下面我们会用到这个保存下来的文件。 第三步：开启Fiddler的请求自动重定向功能 打开AutoResponder标签设置。有没有看到界面上有两个复选框？第一个的作用是开启或禁用自动重定向功能，我们就可以在下面添加重定向规则了。第二个复选框框勾上时，不影响那些没满足我们处理条件的请求。 第四步：创建重定向规则，将目标是这个js的HTTP请求重定向到本地文件 我们可以通过“Add…”按钮手动添加规则，不过这个URL已经出现在我们的session列表中，可以直接拖动过来。在左侧的Session列表中选择第一步找到的session，拖动到AutoResponse标签中。这样就创建了一个针对这个URL的规则。 Fiddler帮我们生成的规则是： 当URL为：http://www.aliued.cn/wp-includes/js/comment-reply.js?ver=20090102 返回200，使用和Session 4一模一样的内容返回 我们需要修改这个规则， 选择“Find a file…”，就可以选择本地的文件作为返回的body内容。 选择我们刚刚保存下来的文件。 刷新一下浏览器页面，看一下session列表，如果像下面这样，这个session的底色是灰色的，那么恭喜你，你已经成功将这个请求重定向到本地文件了！ tip: 如果浏览器用的是Firefox，记得先清一下临时文件缓存，因为Firefox是真正的缓存，当判断文件的缓存还未过期时，就不会再发请求出来，Fiddler就获取不到了。 第五步：修改本地文件，进行测试 我们在本地的js文件中加一句alert(‘hello’) 刷新浏览器，看看效果，如果alert出来，那就成功了。 继续修改这个文件并测试，成功修复问题后，我们就可以发布修改后的文件了。 小结：自动重定向功能是Fiddler最实用的功能，这里的Rule可以自由地设定，可以使用搜索（默认）、精确匹配（EXACT）、正则表达式匹配（REGEX）。处理方式可以选择使用文件，也可以选择合适的时间暂停数据流（bpu、bpafter），人工干预。通过以上几个步骤，我们演示了怎样将HTTP请求重定向到本地的文件，进行web调试。这种调试方式不需要发布到线上再验证，避免了修改不成功、对用户造成影响的风险，而且不需要搭建复杂的开发服务器等开发环境，非常适合快速web调试。 延伸阅读： Fiddler使用帮助 Fiddler AutoResponder标签说明]]></description>
			<content:encoded><![CDATA[<p><img class="alignnone size-full wp-image-429" title="fiddler-title" src="http://www.aliued.cn/wp-content/uploads/2010/04/1-13.jpg" alt="" /></p>

<p>在<a href="http://q.pnq.cc/archives/368">上一篇（介绍篇）</a>中，我们对<a href="http://www.fiddler2.com/fiddler2/">Fiddler Web Debugger</a>有了简单的接触，也许你已经开始在用Fiddler进行HTTP相关的调试，在这一篇，我们将通过一个实例了解Fiddler的神奇魔法。</p>

<p>在我们前端开发的日常工作中，发现服务器上某个css/javascript文件有问题，需要修改，那真是家常便饭。通常，我们需要将文件进行修改，然后重新发布再验证，这样就很容易影响到生产环境的稳定性。更普遍的做法是，我们在开发环境中修改文件并验证，然后发布到生产环境。虽然安全，却比较繁琐。而利用Fiddler的可以修改HTTP数据的特性，我们就非常敏捷地<strong>基于生产环境</strong>“修改——验证——发布”。<span id="more-422"></span></p>

<p>假设我们发现<a href="http://www.aliued.cn/?p=2335" target="_blank">这个页面</a>有问题，需要修改所引用的js文件（<a href="http://www.aliued.cn/wp-includes/js/comment-reply.js?ver=20090102">http://www.aliued.cn/wp-includes/js/comment-reply.js?ver=20090102</a>）。</p>

<h2>第一步：用Fiddler查看页面的数据流列表，找到这个js文件的session</h2>

<p><a href="http://q.pnq.cc/wp-content/uploads/2010/04/image.png"><img style="display: inline; border: 0px initial initial;" title="image" src="http://www.aliued.cn/wp-content/uploads/2010/04/image_thumb2.png" border="0" alt="image" /></a></p>

<blockquote>tip: 最好是没有缓存的返回内容（Result Code是200），这样可以进行下一步的保存。不是200也没关系，你只要本地硬盘上有这个文件就好了。</blockquote>

<h2>第二步：将js文件保存到本地（如果本地已经有这个文件，可以跳过这步）</h2>

<p><img style="display: inline; border: 0px initial initial;" title="image" src="http://www.aliued.cn/wp-content/uploads/2010/04/image11.png" border="0" alt="image" /></p>

<p>在这个js session上右键点击，选择“Save – Response –Response Body…”，将js文件的内容保存到本地。记住存的位置，下面我们会用到这个保存下来的文件。</p>

<h2>第三步：开启Fiddler的请求自动重定向功能</h2>

<p><img style="display: inline; border: 0px initial initial;" title="image" src="http://www.aliued.cn/wp-content/uploads/2010/04/image21.png" border="0" alt="image" /></p>

<p>打开AutoResponder标签设置。有没有看到界面上有两个复选框？第一个的作用是开启或禁用自动重定向功能，我们就可以在下面添加重定向规则了。第二个复选框框勾上时，不影响那些没满足我们处理条件的请求。</p>

<h2>第四步：创建重定向规则，将目标是这个js的HTTP请求重定向到本地文件</h2>

<p>我们可以通过“Add…”按钮手动添加规则，不过这个URL已经出现在我们的session列表中，可以直接拖动过来。在左侧的Session列表中选择第一步找到的session，拖动到AutoResponse标签中。这样就创建了一个针对这个URL的规则。</p>

<p><img style="display: inline; border: 0px initial initial;" title="image" src="http://www.aliued.cn/wp-content/uploads/2010/04/image31.png" border="0" alt="image" /></p>

<p>Fiddler帮我们生成的规则是：</p>

<ul>
    <li>当URL为：<a title="http://www.aliued.cn/wp-includes/js/comment-reply.js?ver=20090102" href="http://www.aliued.cn/wp-includes/js/comment-reply.js?ver=20090102">http://www.aliued.cn/wp-includes/js/comment-reply.js?ver=20090102</a></li>
    <li>返回200，使用和Session 4一模一样的内容返回</li>
</ul>

<p>我们需要修改这个规则，</p>

<p><a href="http://q.pnq.cc/wp-content/uploads/2010/04/image4.png"><img style="display: inline; border: 0px initial initial;" title="image" src="http://www.aliued.cn/wp-content/uploads/2010/04/image_thumb11.png" border="0" alt="image" width="467" height="337" /></a></p>

<p>选择“Find a file…”，就可以选择本地的文件作为返回的body内容。</p>

<p><img style="display: inline; border: 0px initial initial;" title="image" src="http://www.aliued.cn/wp-content/uploads/2010/04/image51.png" border="0" alt="image" /></p>

<p>选择我们刚刚保存下来的文件。</p>

<p>刷新一下浏览器页面，看一下session列表，如果像下面这样，这个session的底色是灰色的，那么恭喜你，你已经成功将这个请求重定向到本地文件了！</p>

<p><img style="display: inline; border: 0px initial initial;" title="image" src="http://www.aliued.cn/wp-content/uploads/2010/04/image61.png" border="0" alt="image" /></p>

<blockquote>tip: 如果浏览器用的是Firefox，记得先清一下临时文件缓存，因为Firefox是真正的缓存，当判断文件的缓存还未过期时，就不会再发请求出来，Fiddler就获取不到了。</blockquote>

<h2>第五步：修改本地文件，进行测试</h2>

<p>我们在本地的js文件中加一句alert(‘hello’)</p>

<p><img style="display: inline; border: 0px initial initial;" title="image" src="http://www.aliued.cn/wp-content/uploads/2010/04/image71.png" border="0" alt="image" /></p>

<p>刷新浏览器，看看效果，如果alert出来，那就成功了。</p>

<p>继续修改这个文件并测试，成功修复问题后，我们就可以发布修改后的文件了。</p>

<p>小结：自动重定向功能是Fiddler最实用的功能，这里的Rule可以自由地设定，可以使用搜索（默认）、精确匹配（EXACT）、正则表达式匹配（REGEX）。处理方式可以选择使用文件，也可以选择合适的时间暂停数据流（<em>bpu、</em>bpafter），人工干预。通过以上几个步骤，我们演示了怎样将HTTP请求重定向到本地的文件，进行web调试。这种调试方式不需要发布到线上再验证，避免了修改不成功、对用户造成影响的风险，而且不需要搭建复杂的开发服务器等开发环境，非常适合快速web调试。</p>

<p>延伸阅读：</p>

<ol>
    <li><a href="http://www.fiddler2.com/Fiddler/help/">Fiddler使用帮助</a></li>
    <li>Fiddler <a href="http://www.fiddler2.com/Fiddler2/help/AutoResponder.asp">AutoResponder标签说明</a></li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://q.pnq.cc/archives/422/feed</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
	</channel>
</rss>

<!-- Served from: q.pnq.cc @ 2012-02-07 05:19:41 by W3 Total Cache -->
