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>'
var jIO = $('#Upfiler_file_iframe'); jIO.load(function(){ var result = eval('(' + $(jIO[0].contentWindow.document.body).text() + ')'); });