日期:2014-05-16  浏览次数:20341 次

javascript,php文件上传详解

?? ? 今儿说点儿基础但是蛮重要的前端技术——使用file input实现文件上传。

?? ?话说很久以前,我一直以为鼠标在点击file input,弹出dialog,选择文件点”打开“以后,文件就自动上传了的,现在终于知道,自己太傻太天真了。操作系统才不会自动帮你做那个事情捏~ 今天跟踪了下js执行的流程,知道了真正执行上传动作之前在本地客户端到底完成了哪些动作。


?

?? ?当点击dialog中的”打开“后,客户端执行的唯一操作是改变file input的value,并把file input的相关文件参数赋给包裹它的form,比如,input的name是pic1,那么此时,form下就多了一个叫做”pic1“的对象属性,下面是这个属性在form中的样子,this就是那个form对象:

?

看到我画框的那个地方了吗?对,就是那个‘files’属性,这个才是整个上传的关键,它里面装的就是真正的要上传的文件的相关数据,展开看看,



?? 里面包含文件名,大小,类型以及二进制获取方法等信息,这些在上传过程中都是关键的信息。

?

?? 接下来,一般会选择两种方式触发form的提交:

?? 1. file input的onchange中自动调用form.submit;

?? 2. 添加一个submit型的input,点击提交。

?

?? form要正确实现上传提交要具备几个必须要素:

?? 1. 有一个action,我的后台使用php写的,因此我的action叫做'/upload/do_upload'(我的没有php后缀,是因为我使用了codeigniter这个框架。)。

? ?2.?method="POST"

? ?3. enctype="multipart/form-data"

?

? ?form提交到后台以后是什么样子呢?按照action的设定,后台php文件中存在一个do_upload方法,在该方法中,你可以取到一个系统变量,叫做$_FILES,用firephp跟踪一下看看$_FILES中有什么数据:


?

由上图可知,$_FILES是一个数组,它的元素就是我们前端传过去的文件数据,在本例子中就是pic1,pic1中包含一些file信息。

接下来就要真的传文件到服务器了。在form提交以后,服务器会以临时文件的形式保存上传文件。我们需要做的,只是把这个临时文件copy到服务器目标文件夹。执行方式如下,

copy($_FILES['pic1']['tmp_name'], WEB_PATH.'/tmp/'.$user_uid.'.'.$file_type);

?

‘copy’是php的内置函数。第一个参数代表临时文件地址,第二个参数是目标文件路径。

特别要注意的是,你要事先创建这个WEB_PATH.'/tmp/'的路径,否则上传文件会找不到位置。

?

执行完这一步,去你的服务器文件夹下看一看,就会发现新文件已上传成功了。

?

文件上传成功后,总要做些回调处理,比如显示下预览图或者文件上传格式不正确时,返回错误信息。你可以直接echo返回,也可以自己写一个json解析函数,返回。

?

返回后这些信息如何接收是最后一个问题了。一般通用的方法时为
1. form设置target属性,如:target="Upfiler_file_iframe"。

2. 创建一个name为"Upfiler_file_iframe"的iframe,记得隐藏哦,因为他就是用来装数据的:

?'<iframe frameborder="0" src="about:blank" name="Upfiler_file_iframe" id="Upfiler_file_iframe" class="fb_img_iframe" style="display:none;"></iframe>'?


如此这般,后台上传函数执行完成后,返回的数据就会被塞到这个iframe中,那怎么取出来呢?我假设你用了JQuery库,则做下面的操作:

var jIO = $('#Upfiler_file_iframe');
jIO.load(function(){
   var result = eval('(' + $(jIO[0].contentWindow.document.body).text() + ')');
});

? ?jIO.load会在文件上传成功后,自动被调用;而 $(jIO[0].contentWindow.document.body).text()装的就是你从后台返回的信息。
你可能注意到我用了eval(),这是为什么呢?
原因是,我返回的数据是json格式,但是经过text()取值后,返回结果变成了全字符串格式,我需要eval一下,把它变回
对象,这样我才能通过"."的形式把我要的数据拿出来。之后你就可以为所欲为了:去掉加载图标,插入预览图等等。
? ?至此,文件上传的操作就全部结束了。
??
? ?备忘结束,也希望给来串门的其它同道以帮助。

1 楼 univasity 2011-11-04  
非常不错,很全面。学习了。