如果ajax失败,Dropzone.js将重试

时间:2013-12-07 23:19:35

标签: javascript ajax file-upload dropzone.js

我正在使用dropzone.js将某些文件上传到我的服务器。我有一个问题,有时服务器无法跟上连接并拒绝一些上传,因此它们将失败并用x标记为红色。我想在一定时间后自动重试,或者至少让用户能够手动重启它。

dropzone.js中是否有一个实现的功能,这是一种为我自己实现它的简单方法,还是有更好的工具可以通过拖放,预览,ajax等进行上传...?

3 个答案:

答案 0 :(得分:2)

需要对dropzone.js进行一些小修改才能使事情看起来很漂亮,否则它只是一个指令 我的dropzone现在重试(无限期,但我稍后会解决)直到它成功。重置进度条需要做更多的工作,但这应该足以让你到达某个地方(如果你仍然关心这一点)。

对dropzone.js的编辑是(在美化版本中):

                    success: function(file) {
                    file.previewElement.classList.remove("dz-error");
                    return file.previewElement.classList.add("dz-success");
                }

我添加了删除行。当文件成功上传时,这会将Xs更改为刻度 角度指令如下:

.directive('dropZone', function($rootScope) {
        return function ($scope, element, attr) {
            var myDropZone = element.dropzone({
                url: "api/ImageUpload",
                maxFilesize: 100,
                paramName: "uploadfile",
                maxThumbnailFilesize: 5,
                autoProcessQueue: false,
                parallelUploads: 99999,
                uploadMultiple: false,
                // this is my identifier so my backend can index the images together
                params: {identifier: $scope.identifier},
                // I seem to need to do this when a file is added, otherwise it doesn't update
                init: function(){this.on("addedfile", function(file){$rootScope.$digest();})}
            });
            // grabbing the dropzone object and putting it somewhere the controller can reach it
            $scope.dropZone = myDropZone.context.dropzone;
            // what we use to work out if we're _really_ complete
            $scope.errors = [];
            // here is our retry mechanism
            myDropZone.context.dropzone.addEventListener("error", function(file,errorMessage,xhr)
            {
                // log our failure so we don't accidentally complete
                $scope.errors.push(file.name);
                // retry!
                myDropZone.context.dropzone.uploadFile(file);
            });
            myDropZone.context.dropzone.addEventListener("success", function(file,errorMessage,xhr)
            {
               // remove from the error list once "success" (_not_ "complete")          
               $scope.errors.splice($scope.errors.indexOf(file.name), 1);
            });
             // this gets called multiple times because of our "retry"  
            myDropZone.context.dropzone.addEventListener("queuecomplete", function()
            {
                 // if we're here AND have no errors we're done
                if($scope.errors.length == 0)
                {
                      // this is my callback to the controller to state we're all done
                    $scope.uploadComplete();
                }
            });
        };
    })

不确定是否所有myDropZone.context.dropZone都是必要的,我有点傻于javascript并花费我很多时间在console.logging()对象上并在调试器中检查它们。这是我找到dropzone组件的地方,也许有一种更简单的方法?

答案 1 :(得分:1)

我的解决方案是不更改Dropzone库,只有4行。我尝试上传文件两次,因为第一个失败的请求设置了一个基于新的cookie的CSRF令牌:

var isFirstTry = true;

myDropzone = new Dropzone(document.body, {
    init: function() {
        this.on("sending", function(file, xhr, formData) {
            xhr.setRequestHeader("X-CSRF", Cookies.get('CSRF'));
        });
    },
    error: function(file, errorMessage, xhr){
        if (errorMessage && errorMessage.status === 405 && file && isFirstTry) {
            isFirstTry = false;


            //remove item from preview
            this.removeFile(file)

            //duplicate File objet
            new File([file], file.name, { type: file.type });




            this.uploadFile(file);
        }
    },
    // other configs
});

在dropzone error事件之后,无论结果是什么,dropzone都会触发complete事件。完成dropzone后,将状态元素设置为complete。这隐藏了进度条。要防止此行为,请复制File对象。这会阻止complete hook处理新的预览元素。

答案 2 :(得分:0)

我的情况与Quibblesome略有不同,但我的解决方案是基于他们的答案......所以,谢谢Quibblesome !!!!

在我的情况下,ajax没有失败,所以dropzone.addEventListener("错误",函数(file,errorMessage,xhr)从未被触发。所以我改变了Quibblsomes解决方案即使dropdzone触发成功。



var fileObj;
clientDetailsDropZone = new Dropzone($("#clientDetailsDropZoneArea").get(0), {
  init: function()
	{ 
		this.on("success", function(e,response)
		{
		   //IF THE USERS authtoken is expired..... retry the upload automatically
			if(!authToken.isValid)
			{
				//Get a new Token and then autmoatically re upload -- getFileAuthToken is another ajax call that authorizes the user
				getFileAuthToken(function f(e){
					this.uploadFile(fileObj);				
				});
			}
			else
			{	//They had a good token and the upload worked
				alert("yay your upload worked!");
			}
		});

		this.on("addedfile", function(file) {
			fileObj = file;
		});
	}
});