上传文件 file upload 学习笔记
2015-04-12 12:43
288 查看
这里我只会说说一些完成 file upload 的基础 API。
很多项目我们需要上传文件。
有简单的 input file, 有需要验证的,有需要压缩的(img),有需要分段的(video),有需要体验好(display on local, ajax & percent) 等等
要完成以上的所有需求,我们需要很多底层的 API, 比如 File, FileReader, Canvas , XMLHttpRequest , Blob
要把这个控件写好的话,需要一些设计模式,不过这篇不会涉及这个,我只是想大略的说说过程和使用到的API方法,如何去设计就交给你们自己了。
参考 :
http://javascript.ruanyifeng.com/bom/ajax.html http://www.html5rocks.com/zh/tutorials/file/dndfiles/ https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toDataURL http://www.w3schools.com/tags/canvas_drawimage.asp https://developer.mozilla.org/en-US/docs/Web/API/Blob/slice http://www.codicode.com/art/upload_and_save_a_canvas_image_to_the_server.aspx
基本的步骤是这样的
1. input file addEventListener change 监听 input file (你要用 drag drop 替代也行)
2. 得到 file 对象之后你就可以检查 file.name,file.type,file.size 等等了
3. 我可以通过 FileReader.readAsDataURL(file); 来获取一个 base64 string (这个是针对图片的处理,如果是txt的话你可以用别的 FileReader.readAs...其它)
4. 把这个 base64 放入img.src = base64 的话就可以在本地显示图片了
5. 在打开一个canvas 后,我们可以把上面的这张相片放入 canvas , 修改它的尺寸,加水印等等.
6. canvas.toDataURL() 把图像转换回 base64 string.
7. 通过XMLHttpRequest 上传这个 base64 string. (XMLHttpRequest 可以监听 process percent)
8. 后端把 base64 convert to byte 写入 fileStream 就完成了。
如果要支持分段上传的话,base64应该直接substring记入index position 就可以了。
如果上传的是 file 不是 base64 的话,可以使用 Blob.webkitSlice() | Blob.slice
有一点要说明一下,canvas to base64 png 的话,size 是非常大的, 比源文件还要大的多,所以png 格式是不能通过canvas做压缩的. (如果我错了,请告诉我)
所以一般上我们是对jpeg做压缩, 质量设置成0.92 的话,size 会和源文件相同. 不过0.92并不是default的设置,default设置会再低一些。
上面我没有实现水印和分段,以后等我有时间写一个完整的控件时,我才更新。
很多项目我们需要上传文件。
有简单的 input file, 有需要验证的,有需要压缩的(img),有需要分段的(video),有需要体验好(display on local, ajax & percent) 等等
要完成以上的所有需求,我们需要很多底层的 API, 比如 File, FileReader, Canvas , XMLHttpRequest , Blob
要把这个控件写好的话,需要一些设计模式,不过这篇不会涉及这个,我只是想大略的说说过程和使用到的API方法,如何去设计就交给你们自己了。
参考 :
http://javascript.ruanyifeng.com/bom/ajax.html http://www.html5rocks.com/zh/tutorials/file/dndfiles/ https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toDataURL http://www.w3schools.com/tags/canvas_drawimage.asp https://developer.mozilla.org/en-US/docs/Web/API/Blob/slice http://www.codicode.com/art/upload_and_save_a_canvas_image_to_the_server.aspx
基本的步骤是这样的
1. input file addEventListener change 监听 input file (你要用 drag drop 替代也行)
2. 得到 file 对象之后你就可以检查 file.name,file.type,file.size 等等了
3. 我可以通过 FileReader.readAsDataURL(file); 来获取一个 base64 string (这个是针对图片的处理,如果是txt的话你可以用别的 FileReader.readAs...其它)
4. 把这个 base64 放入img.src = base64 的话就可以在本地显示图片了
5. 在打开一个canvas 后,我们可以把上面的这张相片放入 canvas , 修改它的尺寸,加水印等等.
6. canvas.toDataURL() 把图像转换回 base64 string.
7. 通过XMLHttpRequest 上传这个 base64 string. (XMLHttpRequest 可以监听 process percent)
8. 后端把 base64 convert to byte 写入 fileStream 就完成了。
如果要支持分段上传的话,base64应该直接substring记入index position 就可以了。
如果上传的是 file 不是 base64 的话,可以使用 Blob.webkitSlice() | Blob.slice
document.getElementById("file").addEventListener("change", function (e) { var files = S.toArray(this.files); var file = files[0]; var fileReader = new FileReader(); fileReader.onloadend = function (e) { var img = new Image(); img.onload = function () { //比例要是尺寸 var MAX_WIDTH = 2560 / 2; var canvas = document.getElementById("canvas"); var context = canvas.getContext("2d"); var height = this.height * (MAX_WIDTH / this.width); canvas.width = MAX_WIDTH; canvas.height = height; //画图 //参数就是把img 的x,y,widthLength,heightLength copy //然后 paste to canvas 的 x,y,widthLength,heightLength context.drawImage(this, 0, 0, this.width, this.height, 0, 0, MAX_WIDTH, height); var base64 = canvas.toDataURL("image/jpeg", 0.8); //default 会是 png 格式,第2参数是压缩质量 0-1 (png 不可以压缩) base64 = base64.replace(/^data:image\/(png|jpeg);base64,/, ""); //后端保存的时候不可以有前面这些字,所以在这里先去除 var http = new XMLHttpRequest(); var formData = new FormData(); formData.append("file", base64); http.open("POST", "//localhost:8054/module/Upload/UploadAjax.ashx", true); http.onreadystatechange = function () { if (this.readyState == 4) { if (this.status == 200) { var imgSrc = this.responseText; } else if (this.status == 0) { //abort 会"同步"执行这里 } else { log("file upload ajax fail, looping upload stoped. statusCode : " + this.status); } } } http.upload.onprogress = function (e) { if (e.lengthComputable) { var percent = parseFloat(e.loaded / e.total * 100).toFixed(0); //八仙 } } http.send(formData); } img.src = this.result; } fileReader.readAsDataURL(file); }, false);
//upload base64 的处理 string path = context.Server.MapPath(@"~\img\" + "abc.jpeg"); using (FileStream fs = new FileStream(path, FileMode.Create)) { using (BinaryWriter bw = new BinaryWriter(fs)) { byte[] data = Convert.FromBase64String(context.Request.Form["file"]); bw.Write(data); bw.Close(); } } context.Response.ContentType = "text/plain"; context.Response.Write(path); //update file 的处理 string[] fileKeys = context.Request.Files.AllKeys; string fileName = ""; foreach (string fileKey in fileKeys) { HttpPostedFile file = context.Request.Files[fileKey]; string extension = "." + file.ContentType.Substring(6); //string extension = file.FileName.Substring(file.FileName.LastIndexOf(".")); fileName = Guid.NewGuid() + extension; file.SaveAs(context.Server.MapPath(@"~\img\" + fileName)); } context.Response.ContentType = "text/plain"; context.Response.Write(fileName);
有一点要说明一下,canvas to base64 png 的话,size 是非常大的, 比源文件还要大的多,所以png 格式是不能通过canvas做压缩的. (如果我错了,请告诉我)
所以一般上我们是对jpeg做压缩, 质量设置成0.92 的话,size 会和源文件相同. 不过0.92并不是default的设置,default设置会再低一些。
上面我没有实现水印和分段,以后等我有时间写一个完整的控件时,我才更新。
相关文章推荐
- [PHP]文件上传学习笔记
- Struts2学习笔记之文件的上传与下载
- 安装、进程-云计算学习笔记---hadoop的简介,以及安装,用命令实现对hdfs系统进行文件的上传下载-by小雨
- PHP学习笔记:文件上传
- JSP学习笔记:通过UUID为解决中文文件上传后的命名问题
- 【原创】Struts2学习笔记之文件的上传与下载
- Struts 1 学习笔记-4-1(Struts动态表单的测试以及上传文件的应用)
- PHP学习笔记--文件目录操作(文件上传实例)
- php学习笔记(十一)文件上传类的编写
- Django学习笔记(六)Django上传文件
- Struts2学习笔记之文件的上传与下载
- JSP Servlet学习笔记——使用fileupload上传文件
- Java与Flex学习笔记(8)----Flex带进度条的多文件上传(基于Servlet)
- grails学习笔记-文件上传
- Struts2学习笔记14:Struts2的文件上传和下载【续】
- struts2 学习笔记(三)——文件的上传和下载
- 文件的上传下载---struts2学习笔记
- JSP Servlet学习笔记——使用fileupload上传文件
- 【小白笔记】PHP学习之路 (26) --文件上传与下载、配置
- Struts2学习笔记之文件上传