{"action":"created","issue":{"url":"https://api.github.com/repos/fex-team/webuploader/issues/142","repository_url":"https://api.github.com/repos/fex-team/webuploader","labels_url":"https://api.github.com/repos/fex-team/webuploader/issues/142/labels{/name}","comments_url":"https://api.github.com/repos/fex-team/webuploader/issues/142/comments","events_url":"https://api.github.com/repos/fex-team/webuploader/issues/142/events","html_url":"https://github.com/fex-team/webuploader/issues/142","id":31258635,"number":142,"title":"如何实现秒传与断点续传","user":{"login":"2betop","id":2698393,"avatar_url":"https://avatars.githubusercontent.com/u/2698393?v=3","gravatar_id":"","url":"https://api.github.com/users/2betop","html_url":"https://github.com/2betop","followers_url":"https://api.github.com/users/2betop/followers","following_url":"https://api.github.com/users/2betop/following{/other_user}","gists_url":"https://api.github.com/users/2betop/gists{/gist_id}","starred_url":"https://api.github.com/users/2betop/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/2betop/subscriptions","organizations_url":"https://api.github.com/users/2betop/orgs","repos_url":"https://api.github.com/users/2betop/repos","events_url":"https://api.github.com/users/2betop/events{/privacy}","received_events_url":"https://api.github.com/users/2betop/received_events","type":"User","site_admin":false},"labels":[{"id":89995014,"url":"https://api.github.com/repos/fex-team/webuploader/labels/faq","name":"faq","color":"006b75","default":false},{"id":50733920,"url":"https://api.github.com/repos/fex-team/webuploader/labels/question","name":"question","color":"cc317c","default":true}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":90,"created_at":"2014-04-10T16:25:03Z","updated_at":"2016-12-01T00:52:51Z","closed_at":null,"body":"因为这是小众需求，所以默认没有做在webuploader里面，而只是提供[hook接口](http://fex.baidu.com/webuploader/document.html#toc_2)，让用户很简单的扩展此功能。\n\n那么，都有哪些重要的hook接口呢？\n- `before-send-file` 此hook在文件发送之前执行\n- `before-file` 此hook在文件分片（如果没有启用分片，整个文件被当成一个分片）后，上传之前执行。\n- `after-send-file` 此hook在文件所有分片都上传完后，且服务端没有错误返回后执行。\n- ...\n\n对于秒传来说，其实就是文件上传前，把内容读取出来，算出md5值，然后通过ajax与服务端验证进行验证, 然后根据结果选择继续上传还是掉过上传。\n\n像这个操作里面有两个都是异步操作，文件内容blob读取和ajax请求。所以这个`handler`必须是异步的，怎样告诉组件此`handler`是异步的呢？只需要在`hanlder`里面返回一个[promise](http://api.jquery.com/deferred.promise/)对象就可以了，这样webuploader就会等待此过程，监听此promise的完成事件，自动继续。\n\n以下是此思路的简单实现。\n\n``` javascript\nUploader.register({\n    'before-send-file': 'preupload'\n}, {\n    preupload: function( file ) {\n        var me = this,\n            owner = this.owner,\n            server = me.options.server,\n            deferred = WebUploader.Deferred();\n\n        owner.md5File( file.source )\n\n            // 如果读取出错了，则通过reject告诉webuploader文件上传出错。\n            .fail(function() {\n                deferred.reject();\n            })\n\n            // md5值计算完成\n            .then(function( md5 ) {\n\n                // 与服务安验证\n                $.ajax(server, {\n                    dataType: 'json',\n                    data: {\n                        md5: ret\n                    },\n                    success: function( response ) {\n\n                        // 如果验证已经上传过\n                        if ( response.exist ) {\n                            owner.skipFile( file );\n\n                            console.log('文件重复，已跳过');\n                        }\n\n                        // 介绍此promise, webuploader接着往下走。\n                        deferred.resolve();\n                    }\n                });\n            });\n\n        return deferred.promise();\n    }\n});\n```\n## 关于断点续传\n\n其实就是秒传分片，跟秒传整个文件是一个思路。关于md5验证这块，可以ajax请求验证，也可以在文件秒传验证的时候，把已经成功的分片md5列表拿到，这样分片验证的时候就只需要本地验证就行了，减少请求数。\n\n具体实现和思路请查看这里https://github.com/fex-team/webuploader/issues/139\n"},"comment":{"url":"https://api.github.com/repos/fex-team/webuploader/issues/comments/264045714","html_url":"https://github.com/fex-team/webuploader/issues/142#issuecomment-264045714","issue_url":"https://api.github.com/repos/fex-team/webuploader/issues/142","id":264045714,"user":{"login":"wangjunjx8868","id":5389565,"avatar_url":"https://avatars.githubusercontent.com/u/5389565?v=3","gravatar_id":"","url":"https://api.github.com/users/wangjunjx8868","html_url":"https://github.com/wangjunjx8868","followers_url":"https://api.github.com/users/wangjunjx8868/followers","following_url":"https://api.github.com/users/wangjunjx8868/following{/other_user}","gists_url":"https://api.github.com/users/wangjunjx8868/gists{/gist_id}","starred_url":"https://api.github.com/users/wangjunjx8868/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wangjunjx8868/subscriptions","organizations_url":"https://api.github.com/users/wangjunjx8868/orgs","repos_url":"https://api.github.com/users/wangjunjx8868/repos","events_url":"https://api.github.com/users/wangjunjx8868/events{/privacy}","received_events_url":"https://api.github.com/users/wangjunjx8868/received_events","type":"User","site_admin":false},"created_at":"2016-12-01T00:52:51Z","updated_at":"2016-12-01T00:52:51Z","body":"`我注册了   \r\n uploader.register({  \r\n        'before-send' : 'checkchunk'\r\n    }\r\n这个事件后，\r\n  uploader.on('uploadProgress', function (file, percentage) {\r\n            $(\"#ppercentage\").html(percentage * 100 + '%');\r\n        });\r\n这里长得进度始终是0， 我开启了分片上传"}}
{"actor":{"display_login":"wangjunjx8868"}}