Как отправить BLOB-объект, добавленный в formData, в php - PullRequest
0 голосов
/ 07 мая 2018

Проблема : при загрузке больших файлов изображений я обнаружил, что при загрузке на мой AWS server с 1gb memory используется полная емкость, он переходит к использованию 932 mb, что приводит к сбою процесса. Я сохранял это изображение в форме DataURI, а затем где-то прочитал, что сохранение его в виде blob может решить мою проблему. Поэтому я хочу добавить этот BLOB-объект в formData и отправить на сервер, и именно поэтому я задаю этот вопрос. Тем не менее, если будет предложено еще какое-либо предложение, касающееся той же проблемы, чтобы сохранить изображение более эффективным способом, когда речь идет о памяти.

Мотив

Я хочу отправить изображение на сервер в виде blob.

Что я сделал

В настоящее время у меня есть dataURI, который я преобразовал в blob. Далее я добавляю этот BLOB-объект к formData и пытаюсь отправить его на серверную часть / php, используя 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

Я получаю ноль, как в консоли, и я также проверил заголовки, где я вижу formData с именем enter image description here

Как видите, $_POST показывает блоб, но $_POST['blobImage'] показывает ноль.

Решение, которое мне требуется :

Я не так быстр, чтобы php, поэтому я не уверен, правильно ли я отправляю blob или получаю его.

Я приложил все возможные усилия для достижения своих целей.

Спасибо сообществу за помощь.

Ответы [ 3 ]

0 голосов
/ 09 мая 2018

Если вы установите contentType: false в своем вызове jQuery Ajax, вы все равно можете использовать тот же код с formData, а затем получить доступ к файлу на сервере через $_FILES['blobImage']

0 голосов
/ 11 мая 2018

Проблема в том, что $ _REQUEST, и, следовательно, объекты $ _GET и $ _POST, имеют ограничение на количество символов, доступных для них.

post_max_size

в PHP.ini контролирует максимальный размер сообщения.

Браузеры и их реализации $ _GET контролируют ограничение запроса $ _GET. Как это видно в их адресной строке. Например, ограничение IE9 составляет 2000 символов, поэтому если ваш BLOB-объект в запросе $ _GET будет содержать более 2000 символов. Общее мнение состоит в том, что запросы $ _GET должны быть намного меньше, чем 255 байтов. И если вы приблизитесь к этому пределу, будьте осторожны, потому что старые браузеры и протоколы к этому совершенно не готовы.

0 голосов
/ 09 мая 2018

Добавьте следующие три свойства в ваш вызов jQuery Ajax, они необходимы для больших двоичных объектов:

cache: false,
contentType: false,
processData: false

Тогда не используйте formData в свойстве data вашего Ajax Call, вам просто нужно добавить созданный BLOB-объект. Также добавьте небольшой обратный вызов рендеринга (кроме уже используемого файла console.log) для печати изображения. Ваш AJAX-вызов выглядит так:

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

Измените ваш PHP-код на следующий:

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

Что касается использования " php: // input ". Он возвращает все необработанные данные, которые идут после заголовков вашего запроса, и ему все равно, какой это тип, что довольно удобно в большинстве случаев. Принимая во внимание, что $ _ POST будет переносить только те данные, которые были переданы, со следующими типами содержимого:

  • применение / х-WWW-форм-urlencoded
  • многочастному / форм-данных * * тысяча двадцать-один

Если вы действительно хотите использовать FormData , вы можете изменить запрос следующим образом:

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

И вы также должны изменить свой PHP-файл, чтобы получить $ _ FILE . Отправляя данные таким способом, Content-Type запроса будет «multipart / form-data», который будет содержать BLOB-объекты, изображения и, как правило, файлы в $ _ FILES , а остальные в $ _ POST , поэтому " php: // input " не поможет.

<?php
  var_dump($_FILES);
?>

Также имейте в виду, что при загрузке BLOB-объектов таким способом они получат случайное имя, если вы не собираетесь генерировать имена файлов на стороне сервера (что вам, вероятно, следует делать в большинстве случаев) и хотите указать конкретное имя, обозначенное добавив его, вы можете передать его вместе с FormData, например:

formData.append('blobImage',blob, "MyBloBName");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...