目录

Web-Secret图片服务六优化您的用户体验

目录

Web Secret:图片服务(六)——优化您的用户体验

阅读:

l

[Web Secret

:图片服务(一)——构建一个基本的图片服务]( )

l

[Web Secret

:图片服务(二)——扩展您的图片服务]( )

l

[Web Secret

:图片服务(三)——为您的服务加上缓存]( )

l

[Web Secret

:图片服务(四)——重新设计您的存储架构]( )

l

[Web Secret

图片服务(五) ——

提高服务的性能]( )

我们在第一篇就提到了最基本的图片服务需要一个图片上传页面,下面是最简单的

HTML

代码:

<

form

id

=“from1”

action

=“UploadImage.php”

enctype

=“multipart/form-data”>

<

label

for

=“imageTitle”>

标题 : </

label

<

input

type

=“text”

name

=“Title”

id

=“imageTitle”

/><

br

/>

<

label

for

=“imageFile”>

图片 : </

label

<

input

type

=“text”

name

=“ImageFile”

id

=“imageFile”

value

="

请选择文件 "

/><

br

/>

<

input

type

=“submit”

value

="

上传 "

/>

</

form

除了需要在表单增加“

enctype

=“multipart/form-data”

”之外,其它也不用太多的调整。那我们需要怎样的功能呢,才能够使我们精心设计的服务用户体验更好:

l

我希望支持一次性上传多个文件

l

我希望上传过程中可以显示进度

l

我希望限制上传文件的格式,比如只支持

jpg(jpeg)

png

gif

格式的图片

l

因为和其它业务集成(如发

blog

或者帖子),我希望不刷新当前页面

l

……

关于文件上传有相当多成熟的解决方案,而且相当多的方案是和服务器代码集成的,你可以根据自己的需要,大多是基于

JavaScript

解决方案的,你可以通过搜索“

”找到很多脚本类库,如果您是使用

,那么可以通过

找到更多的解决方案,如果是使用

,也有很多的插件可以选择,你可以在

找到很多有用的插件,当然了,还有

等框架可以选择,而针对不同的框架,也提供了对于文件上传的支持。我没有给出具体的链接,只是想解释一下不同需求的技术考虑:

1、 上传多个文件

最简单的做法是在上传表单内放置多个

HTML

元素。另外一种方式就是用脚本动态生成文件上传控件,如

所展示的。

2、 限制上传的文件格式

form

onsubmit

事件中判断文件后缀,如果不符合期望的文件格式,取消表单提交。

3、 不刷新当前页面

我们可以选择用

Iframe

,在

IFrame

内的页面只显示上传相关的页面,比如

CSDN

的发表

blog

页面,然后通过脚本的方式将上传之后的图片地址通知上级页面。

4、 显示文件上传进度

对于上传大文件和批量上传的时候尤其有用,因为文件上传过程中是阻塞的,因为文件大或者网络的缘故,将可能导致阻塞时间过长,另外默认情况下上传的所有数据都在服务器内存缓存,如果上传过大的文件,将有可能导致拒绝服务攻击(

DOS

)。

对于

ASP.NET

,默认情况文件大小的上限是

4MB

,这是在系统的

machine.config

中定义的,当然了,你可以在

web.config

中覆盖,具体如下:

*将默认的大小限制修改为

20480KB* *,也就是

20M* *,超时实践为

240*

<system.web>

</system.web>

这种调整是针对于整个网站而言的,如果不想如此做,可以针对某一个目录进行调整,如

/Upload/ImageUpload.aspx

,只要调整

Upload

目录就可以。

<system.web>

</system.web>

但是对于更大的文件呢,这里完成的仅仅是一步,一篇名为

的文章揭示了更多有关与

IIS

配合完成文件上传的细节。从技术上讲是

利用隐含的

HttpWorkerRequest

,用它的

GetPreloadedEntityBody

ReadEntityBody

方法从

IIS

ASP.NET

建立的

pipe

里分块读取数据,对于每块分块进行分析并存储为临时文件,然后给浏览器一个回调地址,那么浏览器就能够显示当前完成的进度了。这时候需要使用到

HttpModule

,这个时候将会导致原来的文件上传无法获得文件流的情况,当然了,也不是没法解决。目前有几个方案可以选择:

·

MediaChase

公司,

$310

以上)

·

Telerik

公司,

$249

·

(免费,遵守

LGPL

协议)

·

(免费)

PHP

的环境下同样有很多种方案可以选择,我只是列举出几个主要的:

1.

PHP

的创始人

Rasmus Lerdorf

写的

APC

扩展模块来实现,

实现方法:

l

安装

APC

,参照官方文档安装,可以使用

PECL

模块安装方法快速简捷

l

配置

php.ini

,设置参数

apc.rfc1867=1

,使

APC

支持上传进度条功能,在

APC

源码说明文档里面有说明

代码范例:

if

( $_SERVER [ ‘REQUEST_METHOD‘ ] == ‘POST‘ )

{

// 上传请求

$status = apc_fetch ( ‘upload_‘ . $_POST [ ‘APC_UPLOAD_PROGRESS‘ ]);

$status [ ‘done‘ ] = 1 ;

echo

json_encode ( $status ); // 输出给用户端页面里的 ajax 调用,相关文档请自己寻找

exit;

}

elseif

(isset( $_GET [ ‘progress_key‘ ]))

{

// 读取上传进度

$status = apc_fetch ( ‘upload_‘ . $_GET [ ‘progress_key‘ ]);

echo

json_encode ( $status );

exit;

}

else

{

// 其他代码,比如上传表单等

}

2.

使用

PECL

扩展模块

uploadprogress

实现(

3.

UGiA

,可以通过

查阅详细的文档

我们上述谈到的都是标准基于

Ajax

和服务器端实现的,为了让客户端显示更加流畅,我们还有其他技术可以选择:

ü

ActiveX

通过

ActiveX

可以实现你需要的任何功能,比如上传前压缩,转换,也能够上传多图片,对于专业的图片

/

相册网站,提供一个这样的桌面工具也许是不错的选择,微软的

space

相册也提供了

[Windows Live

上载工具]( )

也提供了自己的上传工具。如果您的网站也想用这样的

ActiveX

而又没有能力自己开发的话,可以考虑购买

提供的

,它的强大功能应该能够满足您的业务需求。

限制

ActiveX

控件使用的一个关键因素是需要用户安装,同时涉及到安全的原因,不是特定用途的情况下,一般不会推荐这样的方案。

ü

Flash

Flash 8

开始,提供了

FileReferenceList API

,正是因为如此,你可以利用它来实现多文件上传,同时得到详细的文件上传进度。如果你熟悉

ActionScript

,那么可以利用

Flex

或者

Flash

来编写自己的文件上传组件。利用

flash

的另外一个优势就是可以和

javascript

无缝集成,

[Ajax+Flash

实现多文件上传]( )

》展示了不同的解决方案。

CodeProject

站点上也提供了

鉴于目前

flash

播放器的市场占有率,如果不是出于特殊的原因,您几乎可以不用考虑没有安装

flash

和不支持

javascript

的情况(试想一下,不支持

javascript

,也就别谈

ajax

,不支持

flash,

还有哪个

web 2.0

网站是可以玩的?),这时

flash

作为客户端文件上传的解决方案是不错的选择。

ü

作为号称

flash

杀手的

sliverlight

,目前已经发展到

3.0 Beta

,据微软的数据显示,全球已经

1/4

的浏览器安装了

Sliverlight

运行时,不过在国内的用户数还是值得怀疑的(可爱又该死的番茄花园),同样作为浏览器插件,也有越来越多关于文件上传的解决方案。

上你可以找到

,如果你能够确定你的目标用户已经安装或者允许安装

sliverlight

的话,也不妨考虑。

我们刚才讨论了关键文件上传相关的解决方案,不管是

Ajax

还是

ActiveX

Flash

还是

sliverlight

,都有不同的选择,如果你希望简单又美观的话,

flash+

服务器代码可能是一个不错的选择,比如

asp.net

,让你自己实现进度条或者编写

httpmodule

的话,并不是那么容易的,当然了,如果你有针对语言的完整解决方案,也可以如此使用。

最后我们来看一下图片的显示,作为典型的前端技术,不管是

javascript

还是

flash

或者

silverlight

,要列出清单的话,估计都会超过

1000

个,形形色色的插件、组件都可以帮我们来完成这个工作,至于该如何选择,我的原则是尽可能简单,不要为了特效而无畏地消耗浏览器的运算资源,如果访问您的网站会到导致用户

CPU

过高的话,这不是一件好事情。

如果你的业务比较简单,就选择一个适合自己的插件就可以了,如果比较复杂,需要圈人、

Tag

、留下脚印等等流行的

SNS

功能的话,更好的建议是自己开发,如果特效不是很多,用

ajax

会快一点,如果是特效比较多,虽然

Ajax

也能够完成许多效果的模拟,但是运行效率会存在问题,这时可以选择用

ActionScript

来开发

Flash

,你是设计师,你就选择

Flash

,如果是开发人员,需要大量的和后台数据交互,你选择

Flex

,熟悉

C#

的话,用

Silverlight

也可以。

全文到这里已经讨论了一个图片服务可能涉及的方方面面(至少我想到的)。我的初衷并不是一定要构建一个如此复杂的图片服务,这也是我分成多个篇幅的重要原因,在不同篇幅里关注和讨论的内容是不一样的。我只是希望通过这样的探讨来阐述作为一个架构师(或者在路上)你在面对业务的时候应该如何思考问题。

没有哪一个环节是必须的,但是任何一个问题都有可能是你碰到的,这个时候你对于解决方案的平衡尤为重要,有一些可以简化,有一些需要深入,也有一些可以放弃。而作为

Web

架构师,除了需要考量你技术的全面性,更加考虑你对于业务的理解力和掌控的尺度,只有这样,才能够在你的技术框架设计中找到平衡。

而平衡的能力,是平衡业务与技术实现的能力,也是一个优秀的架构师最基本的素质。

预告:

接下来我将探讨

Web 2.0

网站里头大规模用户的互动问题——

WebIM

,大多网站想提供却发现并不那么容易的事情。我们将会涉及到

Ajax

Comet

和服务器端的大规模用户连接的设计,敬请期待。