위조 전에 uploadify 파일 업로드 HTML5 플러그인의 버전을 작성, 친구가 보지 못한 여기를 클릭 ~ 집에서 많은 친구가, 나 또한 프로젝트에 익숙해 봐 사용자 아바타 업로드, 또는 각 여부 업로드 미디어 파일의 종류뿐만 아니라, 개인 비즈니스의 다양한 요구 충족 될 수있다. 작은 행복.
그러나 아무리 다시 플러그인, 모든 요구 사항을 충족하기 어려운 방법 유연한, 예를 들어, 당신은 2G에 파일을 업로드 할 없습니다. 이제 우리의 네트워크 속도에, 나는 곧 30 분을 통과해야 두렵다. 문제는 당신이 시간의 90 % 수있는 좋은 방법입니다 업로드 실수 가까운 브라우저 또는 손 제스처를 눌러 F5가 완료되지 않을 경우, 모든는 다시 모든 것을 시작해야합니다. 이 사용자 경험은 단순히 너무 나쁘다. 그래서, 그것은 매우 필요한 재개. 내가 설명하지 않습니다 이력서, 이렇게 많은 년간 QQ 패스와 파일이 무엇인지, 우리는 그것을 보았다.
다음은 HTTP이 그 기술적 점이다. 제출 또는 HTML5 FormData의 전통적인 형태의 사용은 "블록 EN"파일을 파일 서버에 제출 한 후 전송받을, 이름 변경 및 기타 작업이며, 따라서 수 없습니다 실시간 부분에 업로드 된 파일 저장. 그리고 http 프로토콜에서, 우리는 긴 연결을 브라우저를 유지할 수 및 파일이 제출 스트림 서버는 형태가 될 수 없습니다. 문제는 수 그래서 특히 다음과 같은 점 주소 :
파일 분할을 업로드하려면 시간이 작은 조각을 업로드합니다. 마지막으로 서비스 원래 부품에 추가 서류를 접수 한 후 종료하고 완전한 파일로 병합합니다.
업로드 파일에 각 조각은 파일 크기를 업로드하기 전에이 절단되어야한다, 위치를 결정하기 위해
각 업로드가되면 완전한 업데이트 기록은 파일 크기를 업로드되었습니다
내용은 파일 A 파일 B에 추가되지 않도록 클라이언트와 서버 파일을 확인
의 Zhangxin 쑤 형제를 참조에서 이 글 이 기술은 내 플러그인 Huploadify, HTTP 기능의 성공적인 추가로 배울 수 있습니다. 다른 사람에게 기술과 플러그인합니다.
공사 / 기술 포인트
우리가 10M 파일이있는 경우 것부터 먼저, 명확하게하기 위해, 각 절단 1M를 업로드, 당신은 전체 10 개 요청을 보내야합니다. http 프로토콜에서, 당신은 단지 그렇게 할 수 있습니다. 브레이크 포인트는 세 단계를 완료 업로드 :
파일을 선택한 후에, 서버에 사용자 정의 기능 파일 사이즈를 취득 또는 로컬 저장소에 의해 획득 될 수있다.
받는 제출 된 요청에 따라 제 n 업로드 된 파일의 크기를 절단, 파일 서버 칩을 유지하기 위해 전송 서버는 파일의 내용을 추가하는 것을 계속
업로드하면 파일 크기가 끝을 업로드, 총 파일 크기에 도달
우선, 파일 분할되고, HTML5는 BLOB 데이터 유형을 첨가하고, 데이터의 방법은 분할 될 수 제공 이진 파일 어레이 슬라이스 () 메소드 캔 인터셉트 일부로 슬라이스 () 및 그것의 사용 캐릭터.
때마다 파일 file_put_contents를 추가, 특정 문구 나중에 참조하거나 내 파일을 패키지로 선을 다운로드 할 수 있습니다 다음, 첫번째 file_get_contents와 바이너리 형식 파일을 구 PHP로 작성 내 배경의 추가 조각으로 파일을 저장 하였다.
우리는 또한 다음 컷 업로드하기 전에 올바른하기 위해, 업로드 파일 크기를 저장하는 실제 시간이 필요 다음으로. HTML5 로컬 스토리지의 사용은 다음 읽기 지역을 시작 업로드하기 전에 로컬로 저장의 크기에 업로드 된 방법이다. 그러나이 방법은 매우 제한되어, 사용자는 따로 파일에 사용자 A 페이지가 50 % 업로드하면, 말을하지 않는 로컬 데이터 청지기의 다양한 통해 삭제 설정할 수 있습니다, 다음 페이지 B에 다른 장소에 파일을 업로드하려고 로컬 파일의 결과는 업로드, 분명히 실수를 시작하는 위치에서 직접 50 %, 51 %의 독서를 업로드했습니다. 문제는 로컬 전용 파일 API, 서버의 올바른 파일을하지 않을 권리 일치를 통해 파일의 원래 이름을 얻기 위해, 너무 많은 정보가 저장되지 않습니다. 프로젝트와 실제 그래서, 데이터를 저장하는 서버에 의존해야했다.
서버 측 데이터가있을 것입니다 방법에 대한, 그것은, 내가 약 아래 이야기합니다 프런트 엔드 데이터를 촬영하는 방법이었다.
많은 위에 기술 점은, 사실, 내 플러그인을 사용하는 방법을보기 위해 많은 기술적 인 내용 하 ~이 없다.
사용 재시작 기능
파일의 도입은, 하나의 플러그인에 대한 소개를 참조 할 수 있습니다에 대해 이야기하지 않습니다. 핵심은 몇 가지 구성, 첫번째보기를 추가하는 것입니다 :
데이터는 서버에 저장
사용자 나 사용자 수도의 동작을 설명하기 위해 당신의 상상력을 사용하여 여기에 예기치 않은 동작의 다양한있을 때 업로드 사용하고 있습니다 :
다른 계정을 사용하여 같은 기계는 로그인 같은 파일을 업로드
부분적으로 파일을 업로드 한 다음 다시 업로드 파일의 내용을 수정
파일, 100 % 완료 파일을 다시 업로드 업로드
동일한 페이지를 여러 업로드 버튼이 같은 파일을 업로드하거나 다른 페이지에서 같은 파일을 업로드 할 수있다
仅仅上面四条,是不是情况就够复杂了?再加上你系统还有自己的业务逻辑,所以在服务端保存已上传文件数据是非常有必要的。而且保存数据和获取数据的函数都交给你来定义,抱着插件有足够的灵活性。
因为涉及到了服务端的技术,无法演示,我将我项目中的真实使用场景在此讲解一下,来展示一下如何自已定义方法来实现服务端保存数据的可靠上传。我定义的getUploadedSize函数如下:
文件初始化
文件上传完毕的代码
文件块的处理代码,up6对文件块的处理,以及文件续传的逻辑进行了大幅度的优化,开发者不需要关心续传的细节,因为up6默认就是自动续传
我向后台的某个地址发送一个请求,传递文件名和文件的最后修改时间为参数,后台根据这两个参数来找到与前台所选择的文件对应的服务器上的文件,将服务器返回的文件大小return出去,来被插件使用。为什么要传递这两个参数呢?我们在前台无法知道服务器上的这个文件的名称,所以使用原始文件名作为一个辅助标识。为了防止用户在两次上传间隔修改了文件,我们把文件的最后修改时间也传给服务端,让服务端进行比较,若时间不对应则返回已上传大小为0,重新上传此文件。
再来看后台都要做哪些工作。数据库中需要有一张表来记录每个已文件的情况,包含的字段大致有:
字段 |
描述 |
uid |
用户ID |
id |
文件ID标识(唯一) |
lenSvr |
服务器文件大小 |
lenLoc |
本地文件大小 |
blockOffset |
文件块偏移(在整个文件中的位置) |
blockSize |
文件块大小 |
blockIndex |
文件块索引(基于1) |
blockMd5 |
文件块MD5 |
complete |
当前文件是否已经传完 |
根据client_filename和last_modified_date,再加上系统中的其他关联信息,可以定位到本次上传的文件在服务端的大小,然后返回给客户端。当然这是我自己的用法,你也可以根据自己的需求灵活设计。总之最终的目的就是要找到前台选择的文件在服务器上真正对应的文件,并将已上传大小正确返回。
另外需注意的一点,就是在续传的第二步,不断提交文件片的过程中,也需要服务端准确定位到相应的文件,不能把A的数据追加到B上。采用的方式也是提交fileName和lastModifyDate两个参数(已写在插件内部,可服务端直接获取),服务端找到对应的文件进行追加。
另外再啰嗦一句,后台获取文件的时候需要取成二进制的,而我们提交是使用FormData来提交的,所以PHP代码需要这么写:
file_put_contents('uploads/'.$filename,file_get_contents($_FILES["file"]["tmp_name"]),FILE_APPEND);
如果上面的说明还是不够清楚,就需要你自己来探索一下了,毕竟考虑到插件可能应用在复杂的系统中,很多工作还是需要你来做的。或者你也可以给我留言,我很乐意为你解答疑惑。
该版本的其他改动
从1.0到2.0,Huploadify又新加了很多东西,不过只是新加,使用方式跟之前的没有变化。例如上面的断点续传功能,你如果不想使用,只需设置breakPoints为false即可,插件仍按照以前的方式工作。除了断点续传这个大头,插件还做了如下改动:
增加了onSelect回调函数,在选择了文件之后触发,用法与uploadify官网的一致
up6提供了3个事件,选择文件,选择文件夹,粘贴
用户选择文件时会触发open_files,选择文件夹触发open_folders,粘贴会触发以上两个事件,因为用户可能粘贴的文件和文件夹
删除掉正在上传的文件,中断发送请求
完善了input file组件的accept属性支持,浏览时只显示运行的文件格式,就是这个东东:
4. 对外开放了方法调用接口,upload、stop、cancel、disable、ennable。我在demo中有演示。使用方法如下:var up = $('#upload').Huploadify({
auto:false,
fileTypeExts:'*.jpg;*.png;*.exe;*.mp3;*.mp4;*.zip;*.doc;*.docx;*.ppt;*.pptx;*.xls;*.xlsx;*.pdf',
multi:true
});
up.upload(1);//开始上传文件,接收一个参数,表示上传第几个文件,可传入*上传队列中的所有文件
up.stop();//暂停上传队列中的所有文件,不接收参数。用于开启了断点需传
up.cancel(1);//删除队列中的某个文件,接收一个参数,表示删除第几个文件,可传入*删除队列中的所有文件
up.disable();//使选择文件按钮失效,不接收参数
up.ennable();//使选择文件按钮生效,不接收参数 5. 修改其他已知bug
结束
插件刚刚完成,与我们的后端程序员调试完成了断点续传功能暂未发现问题,欢迎大家在使用的时候给我提任何问题。老实来讲这个功能使用起来还是挺费解的,为了最大程度的保证灵活做成这样,大家可以与我多多交流~
我在demo中使用了本地存储来做已上传文件大小的保存,下载压缩包后可看一下效果。上传一个比较大的视频文件,上传到中间关闭浏览器,再次打开浏览器上传同一个文件,会看到从上次断掉的地方继续上传。
详细内容可以参考我写的这篇文章:http://blog.ncmem.com/wordpress/2019/08/09/%e5%a4%a7%e6%96%87%e4%bb%b6%e4%b8%8a%e4%bc%a0%e8%a7%a3%e5%86%b3%e6%96%b9%e6%a1%88/