doumei7420 2018-05-07 08:42
浏览 464
已采纳

如何将formData中附加的blob发送到php

Issue : While uploading large image files i recognized that while uploading on my AWS server having 1gb memory uses it's full capacity, it goes upto 932 mb usage which causes crash to the process. I was saving that image in the form of DataURI and then I read somewhere that saving it in the form of blob can solve my problem. So i want to append that blob to formData and send to server and this is the reason i come up with this question. However if any else suggestion regarding the same problem to save image more efficient way when memory is concerned, will be appreciated.

Motive

I want to send an image to the server side as in the form of a blob.

What I have done

I am currently having a dataURI which I have converted into a blob. Further, i append that blob to formData and try to send it to server side/php using ajax.

JAVASCRIPT:

function convertURIToImageData(dataURI) {
// convert base64/URLEncoded data component to raw binary data held in a string
  var byteString;
  if (dataURI.split(',')[0].indexOf('base64') >= 0)
    byteString = atob(dataURI.split(',')[1]);
  else
    byteString = unescape(dataURI.split(',')[1]);

// separate out the mime component
  var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];

// write the bytes of the string to a typed array
  var ia = new Uint8Array(byteString.length);
  for (var i = 0; i < byteString.length; i++) {
    ia[i] = byteString.charCodeAt(i);
  }

  return new Blob([ia], {type:mimeString});
 }
//
const dataURIconverter = () =>{
  let img;
  var image = new Image();
  image.crossOrigin = 'anonymous'; // cross domain
  // create an empty canvas element
  var canvas = document.createElement("canvas"),
    canvasContext = canvas.getContext("2d");

  image.onload = function () {
    //Set canvas size is same as the picture
    canvas.width = image.width;
    canvas.height = image.height;
    // draw image into canvas element
    canvasContext.drawImage(image, 0, 0, image.width, image.height);
    // get canvas contents as a data URL (returns png format by default)
    var dataURL = canvas.toDataURL();
    // console.log(dataURL)
    let blob = convertURIToImageData(dataURL)
    console.log(blob)
    var formData = new FormData();
    formData.append('blobImage',blob)
    $.ajax({
        type: 'POST',
        url: 'check.php',
        data: formData,
        processData: false
    }).done(function(data) {
        console.log(data);
    })
  }
    image.src = "https://static.pexels.com/photos/248797/pexels-photo-248797.jpeg"
 }

 dataURIconverter()

PHP

<?php

  var_dump($_POST['blobImage'])
  var_dump($_POST);
        //var_dump($_FILES['image']);

  //$name = $_FILES['image']['tmp_name'];
 //echo $name;
 //echo $_FILES['image']['tmp_name'];

 //$status = move_uploaded_file($name, $_FILES['image']['name']);

//echo 'successfully stored at '.$_SERVER['HTTP_HOST'];
?>

Error

I am receiving null as in console and i also checked the headers where i see formData with the name enter image description here

As you can see, $_POST showing the blob but $_POST['blobImage'] is showing null.

Solution I require:

i am not that quick to php so i am not sure if i am sending the blob in the right way or receiving it.

I have provided my all possible efforts i have taken to achieve my motive.

Thanks to the community for help.

  • 写回答

3条回答 默认 最新

  • douhang8991 2018-05-09 12:03
    关注

    Add the following three properties on your jQuery Ajax call , they are required for blobs :

    cache: false,
    contentType: false,
    processData: false
    

    Then do not use formData in the data property of your Ajax Call , you simply need to add your created blob. Also add a small rendering callback (apart from the console.log you already use) to print the Image. Your AJAX call gets like this :

        $.ajax({
            type: 'POST',
            url: 'check.php',
            data: blob,
            cache: false,
            contentType: false,
            processData: false
        }).done(function(data) {
            document.write("<img src='"+data+"'></img>");
        })
    

    Change your PHP code to the following :

    <?php
      $res = file_get_contents("php://input");
      echo "data:image/jpg;base64,".base64_encode($res);
    ?>
    

    As far as the "php://input" use is concerned. It returns all the raw data that come after the headers of your request and it does not care what type they are which is pretty handy in most cases. Whereas $_POST will only wrap the data that have been passed with the following Content-Types :

    • application/x-www-form-urlencoded
    • multipart/form-data

    If you really want to use FormData then you can change the request to the following :

    $.ajax({
        type: 'POST',
        url: 'check.php',
        data: formData,
        cache: false,
        contentType: false,
        processData: false
    }).done(function(data) {
        console.log(data);
    })
    

    And you should also change your PHP file to get the $_FILE. Sending data this way , the Content-Type of the Request will be "multipart/form-data" which will have blobs , images and generally files on the $_FILES and the rest on the $_POST so the "php://input" will not be helpful.

    <?php
      var_dump($_FILES);
    ?>
    

    Also keep in mind that when uploading blobs this way , they will get a random name , if you are not going to be generating filenames on the Server-Side (which you probably should in most cases) and want a specific name designated by the uploader , then you can pass it along with the FormData like :

    formData.append('blobImage',blob, "MyBloBName");
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?