1.表单上传
最传统的图片上传方式是form表单上传,使用form表单的input[type=”file”]控件,打开系统的文件选择对话框,从而达到选择文件并上传的目的。
form表单上传
表单上传需要注意以下几点:
(1).提供form表单,method必须是post。
(2).form表单的enctype必须是multipart/form-data。
javascript学习交流群:453833554
enctype 属性规定在发送到服务器之前应该如何对表单数据进行编码。默认地,表单数据会编码为 "application/x-www-form-urlencoded"。就是说,在发送到服务器之前,所有字符都会进行编码。HTML表单如何打包数据文件是由enctype这个属性决定的。enctype有以下几种取值:
application/x-www-form-urlencoded:在发送前编码所有字符(默认)(空格被编码为’+’,特殊字符被编码为ASCII十六进制字符)。
multipart/form-data:不对字符编码。在使用包含文件上传控件的表单时,必须使用该值。
text/plain:空格转换为 “+” 加号,但不对特殊字符编码。
默认enctype=application/x-www-form-urlencoded,所以表单的内容会按URL规则编码,然后根据表单的提交方法:
method=’get’ 编码后的表单内容附加在请求连接后,
method=’post’ 编码后的表单内容作为post请求的正文内容。
B. 详解前端文件上传
首先文件上传首先想到的发post,当然还有其他的上传协议,我们这里只介绍发post。
post支持四种content-type:
Content-Type 被指定为 application/x-www-form-urlencoded;其次,提交的数据按照 key1=val1&key2=val2 的方式进行编码,key 和 val 都进行了 URL 转码。
首先生成了一个 boundary 用于分割不同的字段,为了避免与正文内容重复,boundary 很长很复杂。然后 Content-Type 里指明了数据是以 mutipart/form-data 来编码,本次请求的 boundary 是什么内容。消息主体里按照字段个数又分为多个结构类似的部分,每部分都是以 --boundary 开始,紧接着内容描述信息,然后是回车,最后是字段具体内容(文本或二进制)。如果传输的是文件,还要包含文件名和文件类型信息。消息主体最后以 --boundary-- 标示结束。
RFC1867
application/json这个Content-Type都比较熟悉,当然也可以把json放到formData中;
RFC4657
参见RFC,也比较常见。
XML-RFC
在HTML中要有一个包含了文件输入框的form元素,表单里元素的name一定要写,最终形成formData时,是以name作为key值
如果直接在form里写action的话,会刷新表单,同步请求。所以用发送异步post请求方式。
你还可以不借助HTML表单,直接向FormData对象中添加一个File对象或者一个Blob对象:
你还可以使用jQuery来发送FormData,但必须要正确的设置相关选项:
MDN:使用FormData
C. 如何在php上实现文件上传功能
PHP 一般使用 POST 方法上传文件,下面是一个简单的文件上传示例,里面有相关的注释:
up.htm 文件:
----------
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>Up Sample</title>
</head>
<body>
<form action="up.php" method="post" enctype="multipart/form-data">
<!--备注:表单中 enctype="multipart/form-data " 的意思,是设置表单的 MIME 编码。默认情况,这个编码格式是application/x-www-form-urlencoded,不能用于文件上传;只有使用了 multipart/form-data ,才能完整的传递文件数据,进行下面的操作,并且 method 要设置为 "post"-->
File:<br />
<input type="file" name="upfile" size="30"><br />
<!--上传框要设置 type="file"-->
<br />
<input type="submit" value="Upload">
</form>
</body>
</html>
----------
up.php 文件
----------
<?php
if (is_uploaded_file($_FILES["upfile"]["tmp_name"])){
//如果有文件上传
//is_uploaded_file -- 判断文件是否是通过 HTTP POST 上传的,返回布尔值
//$_FILES['upfilename']['...'],其中的 'upfilename' 即为上传框的 name 属性
//$_FILES['upfile']['tmp_name'] -- 文件被上传后在服务端储存的临时文件名,一般是系统默认
if(!eregi('pdf', $_FILES['upfile']['type'])){
//我们这里假设你要上传一个 pdf 文件
//if(!eregi('pdf', $_FILES['upfile']['type'])) 这个是判断上传文件类型的,是不是 pdf 文件,当然,若是想判断是否是 jpg 文件的话,将 pdf 改成 jpg 就可以了,即 if(!eregi('jpg', $_FILES['upfile']['type']))
//$_FILES['upfile']['type'] 是文件的 MIME 类型,如果浏览器提供此信息的话。例如“image/gif”
echo 'The uploaded file is not an pdf File! Please upload a right file!';
}else{
$filename = $_FILES['upfile']['name'];
//$filename = $_FILES['upfile']['name'],这里是指定上传后的文件名,这里使用的仍是原来的文件名字,($_FILES['upfile']['name'] 是原始文件的名字)
if(move_uploaded_file($_FILES["upfile"]["tmp_name"], dirname(__FILE__)."/upload_file/".$filename)){
//这里就是上传文件
//dirname(__FILE__)."/upload_file/".$file_name -- 指定上传的目标文件,假设你要上传的目标文件夹upload_file 是和当前文件(upload.php)在同一文件夹下
//chmod(dirname(__FILE__)."/upload_file/". $file_name, 0444);
//上面注释掉的是用来改变上传后文件的属性,444 即只有执行和读的权限(看情况加上)
echo $_FILES["upfile"]["name"] . " uploaded succeed!!!";
}else{
echo "Can't upload!!!";
}
}
}else{
echo "File is not selected";
}
//需要注意的:
/*
在你的 up.php 同级目录下建立 upload_file 文件夹,来存放上传的文件
在上传之前要看一下 php 的配置文件:php.ini 中的三处设置
1.是否允许文件上传:( file_uploads = On )
2.文件上传的最大 size:( upload_max_filesize )
3.post 的最大 size ( post_max_size ) 这个大小设置成和 uplod_max_filesize 一样大或比 uplod_max_filesize 大
*/
/*
这只是很简单的一个文件上传的例子,为了帮助理解,只是判断了一下上传文件的类型,还可以使用 if 语句来判断上传文件的大小($_FILES['upfile']['type'])),并进行提示控制等,相关可以查阅 $_FILE['upfile'] 数组的各个值分别代表什么
*/
?>