2013年4月24日星期三

开发日记2013-04-25(导师投票系统 202.197.62.108/prosubmit/)


嗯,总算是把一些之前很怪异的bug解决了。甚是爽快。现在归纳一下:
1、这次的bug大部分是在日志里面找到的(/var/log/里面)对应的名字即对应里面的内容
2、出现的问题大致原因有这几类:
   a.路径错误,导致引用出错
   b.权限问题,导致无法上传文件
   c.学会让错误冒出来(比如设置特定的参数)

2013年4月20日星期六

关于Ftp服务器的设置问题

最近一直在弄一个ftp服务器。在设置的过程中状况百出。最主要的是local_root=/var/www 设置好之后,用FileZilla连接总是不会跳到local_root 所设置的 目录,即/var/www 。于是我把/var/www 的权限改了一下,改成chmod 777 /var/www 。接着就好了。

2012年8月8日星期三

[英文学习-翻译]Web做的那五件你所不知道的事

写在前面:一直说要学好英语,却没什么实际行动。直到今天在看Google Reader里订阅的一些牛人的文章时突然有种想翻译的冲动,心想这也是一种英语学习。于是决定从今天开始尽量每天翻译一些自己感兴趣、好玩的文章。这些文章的版权属于原作者。

作者介绍:Eric Bidelman,Google Chrome 团队的高级程序开发工程师,现在致力于向大家呈现使用HTML5和CSS3能达到的一些效果和用途,具体包括CSS灵活盒布局模块(the  CSS Flexible Box Layout Module)和HTML5的文件系统API。www.ericbidelman.com
译者:Penk Zhou。

牛逼的你可以戳此处看原文。原文地址:http://www.netmagazine.com/features/five-things-you-didnt-know-web-could-do

正文:几周前,我在Google I/O 2012上做了一个“Web能干些什么”的演讲:
不像我以前做过的那些尖端(Bleeding edge)的HTML5讲座,这个讲座主要是演示一些最新的web技术的实际应用同时还验证它们的可行性。总之华丽的demo胜过千言万语。没人会相信一大堆技术特性列表的。

在今天的这篇文章中,我将深入分析从Web能干些什么”的演讲中提取的Web能做的最令人不可思议的五件事情。如果看到这些你已经坐立不安,迫不及待的想动手去试试的话,你可以去我的GitHub去找文章中涉及的所有源码。演讲稿的地址在htmlfivecan.com

提醒:文章中涉及到的部分web技术刚刚出来,你最好使用Chrome 21或者版本号更高的Chrome浏览器进行测试。


1. CSS for web apps


CSS已经给我们带来了一些神奇的特效,不过不幸的是CSS在布局和展示方面的能力(特别是绝对布局和漂浮特性)在现代web开发的年代很失败,相当失败。而且问题是,现在我们不但开发网站,还要开发web应用。而开发web应用的需求和开发网站是有很大差异的。许多的CSS的原始结构在构建响应设计这样的场景中显得苍白无力。

幸运的是CSS工作组比我们要想的要远。现在他们提出了一系列的新规范来直接解决应用的布局和设计问题。例如CSS网格布局层次结构区域结构灵活盒布局模块

咱们先来说说这个CSS灵活盒(CSS Flexbox)。

对齐

我特别喜欢灵活盒(Flexbox)因为它使我只需三行CSS代码便能将网页内容在水平和垂直方向都居中。不再要像以前那样使用恶心的top/left 50%,同还要使用负边距等招数。

下面是它的源代码:

  1. .box {
  2.   display: +flex;
  3.   +justify-content: center;
  4.   +align-items: center;
  5.  }
  6. <section class="box">
  7.   <div>A</div><div>B</div><div>C</div>
  8. </section>
注意:整篇文章我都使用“+”来表示不同浏览器的内核前缀(比如“+flex”即 -webkit-flex,-ms-flex等意思)。

这个示例能生成下面的布局:


源码剖析:display:flex是将父容器设为一个“灵活容器”。在上面的插图中红色区域(<section>)就是一个“灵活容器”,它的内容(三个蓝色子项)就是“灵活项”。要将A,B和C三个子项打包置于水平轴和垂直轴的中间,我们只需分别设置 justify-content: center align-items:center即可。

次序和排列

Flexbox厉害的地方远不止这么一些。Flexbox另一个牛逼闪闪的特性就是我们可以通过它完全分隔改变HTML中标记原本展现的次序。遮住要归功于两项新的CSS特性,orderflex-directionOrder控制同级item的展示顺序。Flex-direction更改它们的排列方式(成列或成排)。

我们先把成排排列放一边吧,假如我们要把A,B和C排成一列…这个小菜一碟! flex-direction: column 使A,B,C沿着垂直轴排列,而不是水平轴。记住,这些item默认会按着标记语言中设定好的次序进行渲染,但是我们可以轻易的重写这些。我们只要给B一个比同级item更小的序列值,它就可以比其他子项优先显示。

  1. .box {
  2.   +flex-direction: column;
  3. }
  4. .box > :nth-child(2) {
  5.   +order: -1;
  6. }
效果:




注意,我们没有动过之前的源码。仍然还是A,B和C。只不过是Flexbox赋予了我们独立源代码之外更改内容的编排方式的能力。


灵活性

Flexbox必不可少的特性是就是“灵活性(flexibility)”。除了对齐,排列和次序,Flexbox还可以使item扩展或者收缩来填满它们周围的空间,而这个就需要flex特性来完成。

flex特性需要三个属性值(flex: <'flex-grow'> <'flex-shrink'> <'flex-basis'>)。其中'flex-grow'用正数表示该元素与同级元素相比要扩展多少'flex-shrink'用负数表示该元素要收缩多少。'flex-basis'用来基本方式表示该元素的宽度。

改变前面的示例,我们可以使用flex特性使B变成它同级元素的三倍大:


  1. .box > * {
  2.   +flex: 1 0 auto;
  3. }
  4. .box > :nth-child(2) {
  5.   +flex: 3 0 auto;
  6. }
这就是最后的结果:




Demo

浏览器要求:Chrome 21

这个demo证明了使用CSS Flexbox 创建一个“Holy Grail”布局(包括头部,body的三列,底部)是一件多么容易的事情。最厉害的是,整个app是有响应性的。你试着调整一下你的浏览器窗口大小看看。



浏览器支持情况


这个Flexbox新特性在Chrome 21和IE 10中都能实现。据说 Mozilla 也已经在积极地实现这个特性了。



2.One-way data binding(单向数据绑定)



数据绑定是每个现代的web应用所需要的。在Web组件的MDV出现之前,我们不得不依赖一些AngularEmber像之类的JavaScript框架来填补一些Web开发中的先天不足,不是么?


Angular是目前我最喜欢的MVC框架之一,因为它很简单。使用它时我不需要学习新的API和模版语法。它使用原始的HTML作为模版语言,用纯JS来做逻辑控制。而这也是我所中意的地方。

使用Angular进行单向数据绑定十分简单,用几句标记语言即可:


  1. <div ng-app ng-init="val=25">
  2.   Volume: <input type="range" min="0" max="100" ng-model="val"> {{val}}/100
  3. </div>
当用户滑动滑块的时候,变量val的值开始变化,同时与val相关的变量的值也开始自动重新计算。Angular通过设定隐藏的事件监听器,当变量值改变它便会重新渲染视图来完成这些繁重的事情。



Using HTML5 data-* attributes(使用HTML5 data-* 属性)


结合HTML5特性和使用:before/:after伪元素的妙招也能到做和上面一样的效果。然而,对于HTML5,我们还没有很好的自动绑定机制。整个过程就像下面这样:


  • Model:data-* 使用CSS的attr() 方法来获取值。
  • View: 渲染器生成内容到:before/:after伪元素。
  • How to bind?:建立一个事件监听器来监视变量的值的变化。

实现这个idea之后,我们得到了与Angular示例一样的效果,但是不需要的框架!


  1. <style>
  2. input::after {
  3.   content: attr(data-value) '/' attr(max);
  4.   position: relative;
  5.   left: 135px; top: -20px;
  6. }
  7. </style>
  8. <input type="range" min="0" max="100" value="25">
  9. <script>
  10.   var input = document.querySelector('input');
  11.   input.dataset.value = input.value; // 设定初值
  12.   input.addEventListener('change', function(e) {
  13.     this.dataset.value = this.value; // 更新视图.
  14.   });
  15. </script>
Using <datalist>

也许在HTML5中使用新的<datalist>元素来实现单向数据绑定是更好的(和更易懂的)方式。Opera和FireFox已经支持<datalist>特性好几年了,只不过最近才在WebKit内核上实现。

这种绑定的简要过程如下:

  • Model:<option> <datalist> 里面可能包含的值全部列出。
  • View: 一个常规的<input>元素。
  • How to bind?:通过datalist的id和input的list属性联系起来。

实现源码很简单:

  1. Browsers: <input list="browsers">
  2. <datalist id="browsers">
  3.   <option value="Chrome">
  4.   <option value="Firefox">
  5.   <option value="Internet Explorer">
  6.   <option value="Opera">
  7.   <option value="Safari">
  8. </datalist>
<datalist> 是一个很强大的为 <input> 元素指定预定义的内容的方式。去想想以前从IndexedDB 数据库读取内容的自动补全的表单吧!

浏览器支持情况

信不信由你,现在的浏览器都支持这些无需框架的数据绑定技术。

3.Access a filesystem(文件系统的存取)


大多数像样的web app在它们程序生命周期的某些环节需要对文件进行存取。HTML5 文件系统 API 给web 带来了一个合适的文件系统。不需要插件,过程也不繁琐。有了它,用户可以对数据持久化存入文件,也可以将文件夹持久化到经过沙盒处理的文件系统。(With it, users can persist data to files and folders to a filesystem sandboxed to your web app’s origin.
开启文件系统需要调用 window.requestFilesystem 方法(需要具体标明内核前缀):
  1. window.webkitRequestFileSystem(
  2.   TEMPORARY,       // Storage type: PERSISTENT or TEMPORARY
  3.   1024 * 1024,     // size (bytes) of needed space
  4.   initFs,          // success callback
  5.   opt_errorHandler // opt. error callback, denial of access
  6. );
需要说明的是,我们没有对本地操作系统上面的文档文件夹和图片文件夹进行读写。HTML5 文件系统只能和你 app 所创建的经过沙盒处理的文件系统进行交互。也就是说你也不能更改另一个web app 文件系统中的数据。

这个API经常用来对App缓存进行替换。如下面的源码所示,对一个图片文件进行动态缓存是一件轻而易举的事情:
  1. var xhr = new XMLHttpRequest();
  2. xhr.open('GET', '/path/to/image.png', true);
  3. xhr.responseType = 'arraybuffer'; // We want a byte array, not a string.
  4. xhr.onload = function(e) {
  5.   window.requestFileSystem(TEMPORARY, 1024 * 1024, function(fs) {
  6.     // fs.root is the root DirectoryEntry for the filesystem.
  7.     fs.root.getFile('image.png', {create: true}, function(fileEntry) {
  8.       fileEntry.createWriter(function(writer) {
  9.         writer.onwriteend = function(e) { ... };
  10.         writer.onerror = function(e) { ... };
  11.         writer.write(new Blob([xhr.response], {type: 'image/png'}));
  12.       }, onError);
  13.     }, onError);
  14.   }, onError);
  15. };
  16. xhr.send();

Demos


浏览器要求:Chrome
Filesystem Playground是一个位于HTML5 文件系统 API 上层的图形界面。整个app是以客户端的形式存在。它包含从桌面拖拽文件和文件夹导入到web app,创建空文件夹,预览文件内容,重命名文件,下载等功能特性。

HTML5 Terminal模拟实现了老式的命令行。它同样位于HTML5 文件系统 API 上层。


当你已经通过这些API创建了一些文件之后,我敢说你可以去尝试一下 3d 版的命令行!(After you’ve created a few files, I dare you to try the 3d command!)

浏览器支持情况

目前只有 Chrome 支持 HTML5 文件系统 API。而且照现在的趋势来看,Mozilla将会坚定不移地将IndexedDB作为文件读取的唯一解决方案。在我看来,IndexedDB 如此复杂了使得用它来存储文件或者创建任何形式的文件夹视图变得几乎不可能。(IndexedDB is far too difficult to use for stashing files and creating any kind of a folder hierarchy. )而且还滥用API。在这样的过渡时期,我自己写了一个JS文件系统库idb.filesystem.js ,它能将 HTML5 文件系统 API 集成到那些只支持IndexedDB的浏览器。这就意味着任何支持IDB的浏览器(理论上来说)也能支持HTML5 文件系统 API。所以欢迎使用!

如果想更加深入的研究文件系统 API ,你可以去看看我的书《如何使用HTML5 文件系统 API》。除此之外,你还可以看看filer.js这个JS库。这是一个方便的包装库。它将API抽象成UNIX中一些命令(诸如cp,mv,mkdir等)。(It’s a handy wrapper library that abstracts the API into UNIX calls such as (cp, mv, mkdir))




4.Access native hardware(对本地硬件的操作)



看到这个标题也许你会很激动,“Whaaaat!? Web 不能对本地的硬件进行操作”。对于大部分情况我会给一个肯定的回答。令人悲伤的是,在当下的Web上访问诸如USB,蓝牙和UDP这样的硬件是一件不可能的事。尽管我们已经看到PhoneGap这样的框架在为Web访问硬件铺路,但现在的事实是现阶段的Web并不包含开发者一直在争取甚至争到口吐白沫的那些 API 。(We’ve seen frameworks such as PhoneGap pave the way here – but the fact remains, the drive-by web doesn’t have all of the APIs developers are foaming at the mouth for.)

硬件设备的访问现在已是一个热门话题了。它如此热以至于W3C在2011年8月份成立了一个设备API 工作组(the Device APIs Working Group)来处理急需解决的问题。最近Chrome Apps 和 Firefox OS等一些项目组也开始致力于这个领域的探索和研究。

现在我们能做些什么?(What can we do today?)

web apps充分利用那些与底层硬件相关的高级的JS API 的能力不是一般的强(The ability for web apps to leverage high level JS APIs that sit on top of underlying hardware isn’t foreign web) 。最近几年还是有不少进展的( The last few years have brought us a bunch of this kind of stuff:)。
  • Geolocation API (GPS定位)
  • Device Orientation API (加速度传感器)
  • WebGL (GPU)
  • HTML5 Filesystem API (经过沙盒处理的文件存取)
  • navigator.onLine / navigator.connection (网络连接)
  • Battery API
  • Gamepad API (通过USB访问具体的设备)
  • WebRTC (声音或视频处理) / Web Audio API (系统音频)

…这个列表会越来越长。现在让我们来看看最后一条。

使用麦克风

自从人类诞生以来,方便地对摄像头和麦克风进行访问(无需插件)一直是最令人梦寐以求的事之一。现在迈出的第一步是在Chrome上面实现的 x-webkit-speech 特性:
  1. <input type="text" x-webkit-speech>
这个特性让人兴奋不已。有了它,我们可以毫不费力地访问用户的麦克风,同时也给用户带来了一种全新的同app的交互方式。

说明:值得注意的是,浏览器可以通过接下来几个月出炉的更加健壮的 Speech JavaScript API来扩展 x-webkit-speech这个特性 。

多亏了WebRTC工作组最近的一些工作让我们现在能获得更好的体验。WebRTC的核心就是getUserMedia,这个API能使app获取麦克风和摄像头的访问权限:
  1. <video autoplay controls></video>
  2. window.URL = window.URL || window.webkitURL;
  3. navigator.getUserMedia = navigator.getUserMedia ||
  4.                          navigator.webkitGetUserMedia ||
  5.                          navigator.mozGetUserMedia;
  6. navigator.getUserMedia({audio: true, video: true}, function(stream) {
  7.   document.querySelector('video').src = window.URL.createObjectURL(stream);
  8. }, function(e) {
  9.   console.log(e);
  10. });
对于getUserMedia我最中意的是它对这个平台已存在的一些部分的重用,重用的部分就是HTML5  <video> 。用法是将video.src 这个属性的值常用的视频文件换成了从摄像头产生的BLOB URL。此时视频便可源源不断地传过去了。这种集成就是一个新老API结合很好的例子。(What I really like about getUserMedia is that it’s reusing older parts of the platform, namely HTML5 <video>. Instead of setting the video.src to a movie file, we set it to a blob URL created from the camera stream. A live feed. This kind of integration is a great example of older APIs co-existing with newer ones.)

录制视频

我一直在盼望(现在还没有实现)通过下面的源码可以实现记录本地媒体流(LocalMediaStream):
  1. <input type="button" value="⚫" onclick="record(this)">
  2. <input type="button" value="◼" onclick="stop(this)">
  3. var localMediaStream;
  4. var recorder;
  5. function record(button) {
  6.   recorder = localMediaStream.record();
  7. }
  8. function stop(button) {
  9.   localMediaStream.stop();
  10.   recorder.getRecordedData(function(blob) {
  11.     // Upload blob using XHR2.
  12.   });
  13. }

浏览器支持情况

getUserMedia实现提供基本支持的有Chrome 20(需在 about:flags 中设置), Opera 12和 Firefox 17 (currently nightly)。 在 Chrome 21 中移除了这个特性(The flag is going away in Chrome 21.)。




5.Stream multimedia(多媒体流)



我总听到web开发者问我:“HTML5可以发送音频流么?”。事实证明,绝对可以。秘诀就是结合二进制 WebSockets和Web Audio API 就行。

一直以来通过WebSocket只能发送字符串数据。这个限制阻碍人们利用WebSockets构建相当酷的app。现在web平台已经出现了JS Typed Arrays 和二进制数据。为啥我不能发送一个文件呢?现在HTML5的规范创建者和浏览器厂商开始注意到这个idea,一个包含新的send()方法的实现开始支持二进制的发送。

这个概念和XHR2差不多。你只需简单地你要发送的数据格式设置一下。比如你要发送一个BLOB文件,那你就将.binaryType 属性的值设为 blob即可:
  1. var socket = new WebSocket('ws://example.com/sock', ['dumby-protocol']);
  2. socket.binaryType = 'blob'; // or 'arraybuffer'
  3. socket.onopen = function(e) {
  4.   window.setInterval(function() {
  5.     // Send off data when nothing is buffered.
  6.     if (socket.bufferedAmount == 0) {
  7.       socket.send(new Blob([blob1, blob2])); // presumably image data.
  8.     }
  9.   }, 50); // rate limit us.
  10. };
  11. socket.onmessage = function(e) {
  12.   document.querySelector('img').src = window.URL.createObjectURL(e.data);
  13. };
在接收端(比如onmessage 处理器),我们可以直接通过创建一个BLOB URL来直接使用这个图像文件(e.data)。两端的数据不再需要Base64的加密和解密。而且性能提升不少…这个我中意!

音频通信

二进制websockets可以应用于一些相当有趣的场景,包括音频文件的发送。

不像一般的API一样屏蔽技术细节,你可以查看我的 audio_streamer demo来了解代码是如何运行的。其实,整个过程相当简单:
  1. On the DJ machine:
    a) 使用  Web Audio API  的decodeAudioData() 方法对整个mp3文件进行解码。
    b) 文件一旦解码完成便将整个  AudioBuffer 划分成更小的块。我们不希望一次性发送整个 AudioBuffer 。
    c) 使用一个简单的NodeJS 服务器将划分好的每块(打包成 ArrayBuffer)通过二进制 WebSocket进行发送。
  2. On the listener’s machine:
    a) 当文件即将播放的时候在精确的时间点通过 Web Audio API 装载和编排收到的每个划分块。这种对音频的无缝“接合”在listener看来就像在播放整个文件。
这个工作流程实质上完成了音频的发送。但是如果没有web平台上的二进制 WebSockets 和Web Audio API这两个新特性,音频发送是无法实现的。

WebRTC 数据频道

通过WebRTC工作组的努力,也许文件共享的未来就是 DataChannel API 。不过不幸的是,现在它还只在Chrome 和 FireFox 中实现了(Unfortunately, it’s still being implemented in Chrome and FF)。这个API旨在让实时的端对端的数据传输变成可能。

浏览器支持情况

Chrome, FF, IE 10 和 Safari 支持 二进制 WebSockets。而  Web Audio API 现在仅有Chrome 和 Safari 支持。

总结

关于“本地和Web”的争论仍是一件让我头疼的事情。我是一个 Web 开发者。我不可能一点都不关心本地应用能做些什么同时我关心任何与Web能做的相关的事情!诚然,我们的Web 平台还有许多不尽如人意的地方,但是我们正在通过这些日益增加的API来解决这些差距。诸如 Web Components 这样的事物的出现将会改变我们构建Web App的方式。本着这种期待,我希望看到我们的 web 开发者不要再去参加那些无谓的争论而是将更多的精力转移到 web 能做的事情上来。还有许多人甚至没有意识到web 还能做些什么。( In this spirit, I’d like to see us web folk stop squaring off with the other guys and shift the conversation more around what the web platform can do. A lot of people don’t even realise what’s possible.)

真心希望这篇文章,htmlfivecan.com 和 htmlfivewow.com 能让人们意识到 web 其实往往能做的更多而不只是让人觉得很花哨。(Hopefully this article, htmlfivecan.com, and htmlfivewow.com have proven the web can often do more than meets the eye.)
全文完。