FormData中的Blob为空 [英] Blob in FormData is null

查看:93
本文介绍了FormData中的Blob为空的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试通过远程API通过ajax在android中发送创建的照片.我正在使用相机图片背景插件.

I'm trying to send created photo in android via ajax via remote API. I'm using Camera Picture Background plugin.

照片创建正确,我通过ajax GET请求将其获取,并将其编码为base64格式.在调试工具中,我可以通过GET请求日志查看映像本身.

Photo is created properly, I'm getting it via ajax GET request and encode it to base64 format. In debugging tool I can see image itself through GET request log.

接下来,我将其解析为Blob并尝试将其附加到FormData:

Next I parse it base64 to Blob and try to attach it to FormData:

var fd = new FormData();
fd.append('photo', blobObj);
$.ajax({
  type: 'POST',
  url: 'myUrl',
  data: fd,
  processData: false,
  contentType: false
}).done(function(resp){
  console.log(resp);
}). [...]

但是当我发送FormData时,我在调试器中看到请求中的FormData等于:{photo: null}.

But when I send the FormData I see in debugger that FormData in request equals to: {photo: null}.

顺便说一句.如果我较早尝试console.log我的blobObj,我会看到这是一个斑点,其大小,类型属性和slice方法-为什么在追加到FormData后变成空值?

Btw. if I try to console.log my blobObj earlier, I see it is a blob, with its size, type properties and slice method - why it becomes a null after appending to FormData?

console.log(blobObj);给出:

Blob {type: "image/jpeg", size: 50778, slice: function}

EDIT2-分步代码:

EDIT2 - STEP BY STEP CODE:

我有本地图像的url,我们假设它存储在imagePath变量中.

I have url to local image, let's assume it is stored in imagePath variable.

首先,我得到此文件并将其解析为base64:

First, I get this file and parse it to base64:

function base64Encode(){
  var CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  var out = "", i = 0, len = str.length, c1, c2, c3;

  while (i < len) {
    c1 = str.charCodeAt(i++) & 0xff;
    if (i == len) {
      out += CHARS.charAt(c1 >> 2);
      out += CHARS.charAt((c1 & 0x3) << 4);
      out += "==";
      break;
    }
    c2 = str.charCodeAt(i++);
    if (i == len) {
      out += CHARS.charAt(c1 >> 2);
      RS.charAt(((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4));
      out += CHARS.charAt((c2 & 0xF) << 2);
      out += "=";
      break;
    }
    c3 = str.charCodeAt(i++);
    out += CHARS.charAt(c1 >> 2);
    out += CHARS.charAt(((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4));
    out += CHARS.charAt(((c2 & 0xF) << 2) | ((c3 & 0xC0) >> 6));
    out += CHARS.charAt(c3 & 0x3F);
  }
  return out;
} 

function getFile(fileData){
  var dfd = new $.Deferred();
  $.ajax({
    type: 'GET',
    url: fileData,
    mimeType: "image/jpeg; charset=x-user-defined"
  }).done(function(resp){
    var file = base64Encode(resp);

    dfd.resolve(file);
  }).fail(function(err){
    console.warn('err', err);
    dfd.resolve();
  });

  return dfd.promise();
};

$.when(getFile(imagePath)).then(function(resp){
    var fd = new FormData();

    resp = 'data:image/jpeg;base64,' + resp;

    var imgBlob = new Blob([resp], {type : 'image/jpeg'});

    fd.append('photo', img, 'my_image.jpg');

    $.ajax({
      type: 'POST',
      url: 'myUrlToUploadFiles',
      data: fd,
      processData: false,
      contentType: false
    }).done(function(resp){
      console.log(resp);
    }). [...]
});

推荐答案

我最近还没有做过,但这对我有用.我希望它也对您有用:

I've not done this recently, but this works with me. I hope it also works with you:

function getBase64ImageByURL(url) {
  var dfd = new $.Deferred();
  var xhr = new XMLHttpRequest();
  xhr.responseType = 'blob';
  xhr.onload = function() {
    var reader = new FileReader();
    reader.onloadend = function() {
      dfd.resolve(reader.result);
    }
    reader.readAsDataURL(xhr.response);
  };
  xhr.open('GET', url);
  xhr.send();
  return dfd.promise();
}

function base64ToBlob(base64Image,toMimeType) {
  var byteCharacters = atob(base64Image.replace('data:'+toMimeType+';base64,',''));
  var byteNumbers = new Array(byteCharacters.length);
  for (var i = 0; i < byteCharacters.length; i++) {
    byteNumbers[i] = byteCharacters.charCodeAt(i);
  }
  var byteArray = new Uint8Array(byteNumbers);
  var blob = new Blob([byteArray], {
    type: toMimeType
  });
  return blob;
}



var imageUrl = "https://upload.wikimedia.org/wikipedia/commons/4/49/Koala_climbing_tree.jpg";

getBase64ImageByURL(imageUrl).then(function(base64Image){
  var blob = base64ToBlob(base64Image,'image/jpeg');
  var fd = new FormData();
  fd.append('file', blob, 'my_image.jpg');
  $.ajax({
    url: 'http://your_host/uploads/testupload.php',
    data: fd,
    type: 'POST',
    contentType: false,
    processData: false,
    success:function(res){
      console.log(res);
    },
    error:function(err){
      console.log(err);
    }
  })
});

在服务器端(testupload.php):

On server-side(testupload.php):

<?php

    if ( 0 < $_FILES['file']['error'] ) {
        echo 'Error: ' . $_FILES['file']['error'] . '<br>';
    }
    else {
        $result = move_uploaded_file($_FILES['file']['tmp_name'], $_SERVER["DOCUMENT_ROOT"].$_SERVER["BASE"].'/uploads/'.'my_image.jpg');
        var_dump("image uploaded: ".$result);
    }

?>

move_uploaded_file 成功将上传的图像移动到该目录之前,可能需要修改目录上的某些读/写权限.

It might be necessary to modify some read/write-permissions on a directory before move_uploaded_file succeeds in moving the uploaded image to this directory.

函数 getBase64ImageByURL 已经可以返回blob对象,但是通过返回base64-image,您可以在上传html-image-tag之前向用户显示该图像.

The function getBase64ImageByURL could already return a blob-object but by returning a base64-image you can show an user this image in a html-image-tag before uploading it for instance.

如果不需要向用户显示该图像,那么您还可以缩短所有步骤:

If there is no need to show an user that image, then you can also shorten all steps:

function getBlobImageByURL(url) {
  var dfd = new $.Deferred();
  var xhr = new XMLHttpRequest();
  xhr.responseType = 'blob';
  xhr.onload = function() {
    dfd.resolve(xhr.response);
  };
  xhr.open('GET', url);
  xhr.send();
  return dfd.promise();
}

getBlobImageByURL(imageUrl).then(function(imageBlob){
  var fd = new FormData();
  fd.append('file', imageBlob, 'my_image.jpg');
  console.log(fd.get('file'));// File-object 
  $.ajax({
    url: 'http://your_host/uploads/testupload.php',
    data: fd,
    type: 'POST',
    contentType: false,
    processData: false,
    success:function(res){
      console.log(res);
    },
    error:function(err){
      console.log(err);
    }
  })
});

对两个已修改函数的引用 base64ToBlob getBase64ImageByURL

references to both modified functions base64ToBlob and getBase64ImageByURL

这篇关于FormData中的Blob为空的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆