jquery文件上传 - IE完成回调data.result问题

时间:2012-01-11 04:16:17

标签: jquery internet-explorer plugins file-upload

我正在使用jQuery文件upload plugin

我不使用UI部分,只使用基本部分。

当我执行以下操作时,我在IE中遇到了问题:

$('input#fileupload').fileupload({
    url: '/upload',
    done: function (e, data) {
    if(data.result != null && $.trim(data.result) != '')
        $('a#attachment').html(data.result);
    }
    //......................
<{1>} IE data.result至少是Object(至少IE9,不确定其他人......)

On Chrome / Firefox只是响应Text(来自服务器的简单纯文本)。

想法?

8 个答案:

答案 0 :(得分:50)

我遇到了同样的问题,我认为这是因为IE(甚至9)不支持XHR文件上传。以下是我认为正在发生的事情,以及我的解决方案:

由于Safari 5 +,Firefox 4+和Chrome支持XHR文件上传,因此fileupload插件可以异步传输文件,从而允许来自服务器的纯文本响应。此纯文本响应可通过data.result事件处理程序中的done获得,并且可以轻松使用。

但是,在IE中,文件传输通过隐藏iframe中的整页刷新进行,导致data.result处理程序中的done成为完整的document对象,并带有响应文本包含在<html><body><iframe><pre>标记内。

这不仅使得获取IE中的数据变得很痛苦,而且还使得您在浏览器之间获得不同数据的方式。

我的解决方案:

我将forceIframeTransport选项设置为true,这使得所有浏览器都使用隐藏的iframe传输文件,例如IE。遗憾的是错过了XHR文件上传,但这至少在所有浏览器中都给出了相同的响应。然后,在我的done处理程序中,我从document对象中提取结果,如下所示:

var result = $( 'pre', data.result ).text();

在您的情况下,我认为代码看起来像这样:

$('input#fileupload').fileupload({
    forceIframeTransport: true,
    url: '/upload',
    done: function ( e, data ) {
     var result = $( 'pre', data.result ).text();
     if( result != null && $.trim( result ) != '' )
        $( 'a#attachment' ).html( result );
    }
...

此处还需要注意的是,我服务器的响应的内容类型是&text;&text;&#39; text / plain&#39;。您可能已经注意到,IE有时会提示用户保存或打开json响应。

以下是一些在解决问题时证明有用的链接: https://github.com/blueimp/jQuery-File-Upload/wiki/Browser-support(请参阅下面的&#39; XMLHttpRequest&#39;部分) https://github.com/blueimp/jQuery-File-Upload/wiki/Options(请参阅&#39; forceIframeTransport&#39;约1/3)

希望这有帮助!

答案 1 :(得分:13)

我遇到与上述问题类似的问题,发现将响应类型从application/json更改为text/plain可以解决这些问题。

答案 2 :(得分:5)

实际上这就是jquery.iframe-transport.js的用途(基本版本还包括此插件作为附加参考)。您需要的是将dataType属性设置为jsonjquery.iframe-transport插件将自动解析iframe结果,因此您可以在完成处理程序中使用相同的逻辑。

$('#fileupload').fileupload({
...
    dataType: 'json'
...
});

答案 3 :(得分:4)

我遇到了同样的问题。 IE 9不会触发done回调,但触发always回调。棘手的部分是从参数中提取JSON响应对象。 (尽管文档声称,我没有发现我需要包含jquery.iframe-transport.js。)

我对always回调的实现看起来像这样:

always: function(e, data) {
  var result;
  if (data.textStatus == 'parsererror') {  // IE9 fails on upload's JSON response
    result = JSON.parse(data.jqXHR.responseText);
  } else if (data.textStatus == 'success') {
    result = data.result;
  }

  if (result) {
    // ...perform custom handling...
  }
}

答案 4 :(得分:1)

这里的答案对于理解和解决问题非常有用。我最终得到了一个令人满意的hacky解决方案,允许现代浏览器使用XmlHttpRequest上传,IE9使用iframe(不用IE7 / 8进行测试):

  • 使用jquery.iframe-transport.js,它将负责从iframe中提取响应。只需将其包含在页面中,fileupload插件即可使用它。
  • 在用于上传文件的服务器操作上,返回JSON结果,但content-type设置为"text/plain",以避免IE提示用户打开文件
  • 在完成回调中,手动评估JSON文本
  • 最后,像以前一样使用评估结果对象

这是JS代码:

//file upload
var upload = $(fileUploadElmtId).fileupload({

    dataType: 'text',  //if we use JSON IE9 will ask the user to open the file... see the FileUploadController class
    url: uploadUrl,
    autoUpload: true,

    done: function (e, data) {


        //parse the JSON string that was received from the server - since it was received as text/plain it is not automatically evaluated
        var result = $.parseJSON(data.result);

        $.each(result.files, function (index, file) {
            //do something with the result - in my case it is an array of uploaded files...
        }
    }
}

答案 5 :(得分:0)

感谢@Justin对此的一个很好的解释。我会避免查询“pre”元素,而是做一个像@EnsignRicky评论的简单解决方案

done: function (e, data) {
  var result = data.result[0].body ? data.result[0].body.innerHTML : data.result
}

答案 6 :(得分:0)

我的问题,原因是:跨域。

也就是说:在IE8 / 9中,您的服务器URL应该与您的js文件位于同一个域中。对于jquery.iframe-transport.js基于iframe,您不能跨域。校验 hehe

你不需要将forceIframeTransport设置为true,对于jquery.file-upload.js将判断浏览器本身。

你的服务器应该返回Content-Type:text / html,或者text / plain,你的js可以使用dataType:&#39; json&#39;,没问题。至少,我的是。

调试时,可以在j = 49,try-catch块的jquery.iframe-transport.js中设置断点。如果它可以在那里打破,那意味着使用iframe,你就可以获得响应。此时,您可以在DOM(在iframe中)中看到您的json,但如果您交叉使用,则会得到未定义的响应。

我的代码。没特别:

$('.input-upload').fileupload({
    url: url, 
    dataType: 'json',
    autoUpload: false,
    acceptFileTypes: /(\.|\/)(gif|jpe?g|png)$/i,
    maxFileSize: 999000,
    previewMaxWidth: 114,
    previewMaxHeight: 70,
    previewThumbnail: false,
    xhrFields: {
        withCredentials: true
    }
}).on('fileuploadadd', function (e, data) {
    $.each(data.files, function (index, file) {
        data.submit().success(function (json, textStatus, jqXHR) {
            // on success
        }).error(function (jqXHR, textStatus, errorThrown) {
            // on error
        });
    });
}).on('fileuploadprocessalways', function (e, data) {
    var _this = this;
    var file = data.files[data.index];
    if (file.preview) {
        // 显示图片预览
        var preview = $(this).parent().siblings('.preview');
        preview.append(file.preview).removeHide();
    }
});

答案 7 :(得分:-2)

我认为问题可能出在服务器响应中,您可以确保服务器始终使用以下代码发送正确的标题:

header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . "GMT");
header("Cache-Control: no-cache, must-revalidate");
header("Pragma: no-cache");
header("Content-type: text/x-json");
echo json_encode($array);
exit(0);