0

我正在使用 Jquery_fileupload (JFU) 将文件发送到亚马逊 s3 存储桶。

当用户选择文件时,文件自动上传成功,亚马逊返回状态码 204 no content。为简单起见,我已更改 s3 策略以返回 200 代码。

问题是即使没有错误,JFU 也会为每个文件提供错误消息:

在 Firefox 中它是: SyntaxError: JSON.parse: unexpected end of data

在 chrome 中它是: SyntaxError: Unexpected end of input

任何解决此问题的想法都会有所帮助。谢谢

JFU设置:

    $(document).ready(function() {
      $('#fileupload').fileupload({
        dropZone: $('#dropzone'),
        autoUpload: true,
        paramName: 'file',
        singleFileUploads: false,
        limitMultiFileUploads: 1,
        sequentialUploads: true,
        multipart: true,
        uploadTemplateId: null,
        downloadTemplateId: null,
        filesContainer: $('#upload-files-container'),
        uploadTemplate: function (o) {
          var rows = $();
          $.each(o.files, function (index, file) {
            var row = $('<tr class="template-upload fade">' +
            '<td class="preview"><span class="fade"></span></td>' +
            '<td class="name"></td>' +
            '<td class="size"></td>' +
            (file.error ? '<td class="error" colspan="2"></td>' :
            '<td><div class="progress progress-info progress-striped active">' +
            '<div class="bar" style="width:0%;"></div></div></td>'
            ) + '<td class="cancel"><button class="btn btn-warning">Cancel</button></td></tr>');
            row.find('.name').text(file.name);
            row.find('.size').text(o.formatFileSize(file.size));
            if (file.error) {
              row.find('.error').text(
                locale.fileupload.errors[file.error] || file.error
              );
            }
            rows = rows.add(row);
          });
          return rows;
        },
        downloadTemplate: function (o) {
          var rows = $();
          $.each(o.files, function (index, file) {
            var row = $('<tr class="template-download">' +
            (file.error ? '<td></td><td class="name"></td>' +
            '<td class="size"></td><td class="error" colspan="2"></td>' :
            '<td class="preview"></td>' +
            '<td class="name"><a></a></td>' +
            '<td class="size"></td><td colspan="2"></td>'
            ) + '</tr>');
            row.find('.size').text(o.formatFileSize(file.size));
            if (file.error) {
              row.find('.name').text(file.name);
              row.find('.error').text(
                locale.fileupload.errors[file.error] || file.error
              );
            } else {
              row.find('.name a').text(file.name);
              if (file.thumbnail_url) {
                row.find('.preview').append('<a><img></a>')
                .find('img').prop('src', file.thumbnail_url);
                row.find('a').prop('rel', 'gallery');
              }
              row.find('a').prop('href', file.url);
            }
            rows = rows.add(row);
          });
          return rows;
        }
      })
    });

S3 政策数据(如果有帮助):

def policy_data
  {
    expiration: @options[:expiration],
    conditions: [
      ["starts-with", "$utf8", ""],
      ["starts-with", "$key", ""],
      ["content-length-range", 0, @options[:max_file_size]],
      {bucket: @options[:bucket]},
      {acl: @options[:acl]},
      {success_action_status: "200"}
    ]
  }
end
4

3 回答 3

2

同样,我发现 Jquery_fileupload '失败'是因为格式不正确的 json 响应 - 无论是浏览器问题还是 S3,我不知道。该文件实际上上传得很好,但是无效的 json 会引发错误。

无论如何,我通过设置JFU 选项来修复它:

dataType: 'xml'

然后将响应从 xml 转换为 json。(为此,我使用了x2js库。)

这是我的 AngularJS 'fileuploaddone' 监听器:

$scope.$on('fileuploaddone', function(e, data) {
  var response;
  response = x2js.xml2json(data.result);
  $scope.file_url = response != null ? (_ref = response.PostResponse) != null ? _ref.Location : void 0 : void 0;
});
于 2013-06-28T20:57:21.313 回答
0

将 xml 转换为 json 就可以了。在阅读了 1thrashers 的回答后,我得到了以下解决方案:

function uploaderReady(){
  if($('#fileupload').length){
    // // Initialize the jQuery File Upload widget:
    $('#fileupload').fileupload({
      //forceIframeTransport: true,    // DO NOT SET: https://github.com/blueimp/jQuery-File-Upload/issues/1803
      dropZone: $('#dropzone'),
      autoUpload: true,
      paramName: 'file',
      dataType: 'xml', // S3 returns xml, so expect xml in return
      singleFileUploads: false,
      limitMultiFileUploads: 1,
      sequentialUploads: true,
      multipart: true,
      uploadTemplateId: null,
      downloadTemplateId: null,
      filesContainer: $('#upload-files-container'),
      add: function (e, data) {
        var $this = $(this),
        that = $this.data('blueimp-fileupload') ||
        $this.data('fileupload'),
        options = that.options,
        files = data.files;
        data.process(function () {
          return $this.fileupload('process', data);
        }).always(function () {
          data.context = that._renderUpload(files).data('data', data);
          that._renderPreviews(data);
          options.filesContainer[
          options.prependFiles ? 'prepend' : 'append'
          ](data.context);
          that._forceReflow(data.context);
          that._transition(data.context).done(
            function () {
              if ((that._trigger('added', e, data) !== false) &&
              (options.autoUpload || data.autoUpload) &&
              data.autoUpload !== false && !data.files.error) {
                //check file size, if less than 2mb, upload to heroku, otherwise direct to amazon.
                var form = $('#fileupload');
                if(data.files[0].size < 2097152){
                  form.attr('action', form.data('local-url'));
                }else{
                  form.attr('action', form.data('external-url'));
                }
                data.submit();
              }
            }
          );
        });
      },
      uploadTemplate: function (o) {
        var rows = $();
        $.each(o.files, function (index, file) {
          var row = $('<tr class="template-upload fade">' +
          '<td class="preview"><span class="fade"></span></td>' +
          '<td class="name"></td>' +
          '<td class="size"></td>' +
          (file.error ? '<td class="error" colspan="2"></td>' :
          '<td><div class="progress progress-info progress-striped active">' +
          '<div class="bar" style="width:0%;"></div></div></td>'
          ) + '<td class="cancel"><button class="btn btn-warning">Cancel</button></td></tr>');
          row.find('.name').text(file.name);
          row.find('.size').text(o.formatFileSize(file.size));
          if (file.error) {
            row.find('.error').text(
              file.error
            );
          }
          rows = rows.add(row);
        });
        return rows;
      },
      downloadTemplate: function (o) {
        var rows = $();
        $.each(o.files, function (index, file) {
          var row = $('<tr class="template-download">' +
          (file.error ? '<td></td><td class="name"></td>' +
          '<td class="size"></td><td class="error" colspan="2"></td>' :
          '<td class="preview"></td>' +
          '<td class="name"><a></a></td>' +
          '<td class="size"></td><td colspan="2"></td>'
          ) + '</tr>');
          row.find('.size').text(o.formatFileSize(file.size));
          if (file.error) {
            row.find('.name').text(file.name);
            row.find('.error').text(
              file.error
            );
          } else {
            row.find('.name').text(file.name);
            if (file.thumbnailUrl) {
              row.find('.preview').append('<a><img></a>')
              .find('img').prop('src', file.thumbnailUrl);
              row.find('a').prop('rel', 'gallery');
            }
            row.find('.size').text( (file.size/1024).toFixed(2)+' KB');
            row.find('a').prop('href', file.url);
          }
          rows = rows.add(row);
        });
        return rows;
      }
    });
    $('#fileupload').bind('fileuploaddone', function (e, data){
      var response = $(data.jqXHR.responseText);
      if(data.jqXHR.status == 201 && response.find('Key').text() != ''){
        // amazon solution
        data.result = data;
      }else{
        // local solution
        data.result = {'files': [{
        'name': response.find('name').text(),
        'size': response.find('size').text(),
        'type': response.find('type').text(),
        'url': response.find('url').text(),
        'thumbnailUrl': response.find('thumbnailUrl').text()
        }]}
      }
    }); //end fileuploader
  }
}
$(document).ready(uploaderReady);
$(document).on('page:load', uploaderReady);
于 2013-08-22T02:55:32.380 回答
0

对于那些遇到这个问题的人(就像我一样),假设您已经解决了所有典型的陷阱/错误,剩下的就是浏览器安全性。

  • 确保您发出正确的 json 与 jsonp 请求
  • 并检查 access-control-origin (如果适用)
于 2013-12-04T22:37:44.413 回答