Javascript:将Uint8Array中的二进制数据转换为字符串损坏文件

时间:2016-01-19 21:30:25

标签: javascript jquery ajax encoding base64

我尝试通过标准的jQuery $.ajax调用将视频文件以块的形式上传到服务器。这个过程很简单:

  1. 使用文件对象上的slice()方法读取块
  2. 使用FileReader.readAsArrayBuffer读取生成的blob
  3. 在FileReader.onload回调
  4. 中创建该结果的Uint8Array
  5. 使用String.fromCharCode.apply(null, intArrayName)将其转换为二进制字符串
  6. 将该二进制字符串作为一个块上传到AJAX调用的data属性
  7. 当我完成上传所有块时,服务器的API会抱怨文件上传不完整。为了测试这种方法,我将连接的二进制字符串转换为Blob并让Chrome将其保存到我的下载文件夹中,结果发现我的媒体播放器说该文件无法播放。

    我已阅读此网站上的帖子,other articles建议直接将整数表示的二进制数据转换为字符串会导致数据丢失,并建议将其转换为base64编码的字符串因为Javascript没有像C#那样的StreamContent对象。

    问题是,即使我将Content-Transfer-Encoding设置为base64,我也不会认为API(我们没有写过)会接受它并且可以告诉我需要base64解码。

    我的问题是:这是安全地通过AJAX呼叫发送视频数据的唯一可靠方法吗?如果没有,我还能如何在我的AJAX请求的数据字段中发送它?在互联网上可能有成千上万的这样的上传者,但我找不到有关如何做到这一点的可靠文档。如果事实证明服务器需要期望base64编码,我们可能必须编写一个中间人API来为我们做这个解码。

1 个答案:

答案 0 :(得分:0)

感谢Patrick Evans,事实证明我需要做的就是上传blob本身:

function upload(file) {
  var offset = 0; // what's been sent already
  var fileSize = file.size;
  var chunkSize = 64 * 1024; // bytes

  while (offset < fileSize) {
    var blob = file.slice(offset, chunkSize + offset);

    var urlToUse = ((offset + blob.size) >= fileSize) ? videoFinishBaseUrl : videoContinueBaseUrl;

    $.ajax({
      url: urlToUse,
      method: 'POST',
      data: blob,
      headers: requestHeaders,
      contentType: false,
      processData: false,
      cache: false,
      async: false,
      success: function(data) {
        jQuery('#uploadmsg').text('Finished offset ' + offset);
        offset += blob.size;
      },
      error: function(err) {
        jQuery('#uploadmsg').text(err);
      }
    });

  }
};