简体   繁体   English

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

[英]How to send blob appended in formData to 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. 问题 :在上传大型图像文件时,我认识到在具有1gb memory AWS server上进行上传时会使用其全部容量,但使用时高达932 mb使用率,导致进程崩溃。 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. 我以DataURI的形式保存该图像,然后我读到某个地方以blob的形式保存可以解决我的问题。 So i want to append that blob to formData and send to server and this is the reason i come up with this question. 所以我想将该blob附加到formData并发送到服务器,这就是我提出这个问题的原因。 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 . 我想以blob的形式将图像发送到服务器端。

What I have done 我做了什么

I am currently having a dataURI which I have converted into a blob . 我目前有一个dataURI ,我已将其转换为blob Further, i append that blob to formData and try to send it to server side/php using ajax. 此外,我将该blob附加到formData并尝试使用ajax将其发送到服务器端/ php。

JAVASCRIPT: 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

<?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 我在控制台中收到null,并且还检查了标头,其中看到formData具有以下名称的formData 在此处输入图片说明

As you can see, $_POST showing the blob but $_POST['blobImage'] is showing null. 如您所见, $_POST显示blob,但$_POST['blobImage']显示空。

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. 我不是那么快就用php所以我不确定我是用正确的方式发送blob还是接收它。

I have provided my all possible efforts i have taken to achieve my motive. 我已竭尽全力实现自己的动机。

Thanks to the community for help. 感谢社区的帮助。

Add the following three properties on your jQuery Ajax call , they are required for blobs : 在jQuery Ajax调用上添加以下三个属性,它们是blob所必需的:

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. 然后,不要在Ajax Call的data属性中使用formData ,您只需要添加创建的blob。 Also add a small rendering callback (apart from the console.log you already use) to print the Image. 还添加一个小的渲染回调(除了已经使用的console.log之外)以打印图像。 Your AJAX call gets like this : 您的AJAX呼叫如下:

    $.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代码更改为以下内容:

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

As far as the " php://input " use is concerned. 至于“ php:// input ”的使用。 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 : $ _POST将仅包装通过以下Content-Types传递的数据:

  • application/x-www-form-urlencoded 应用程序/ x-WWW窗体-urlencoded
  • multipart/form-data 多部分/格式数据

If you really want to use FormData then you can change the request to the following : 如果您确实想使用FormData,则可以将请求更改为以下内容:

$.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 . 而且,您还应该更改PHP文件以获取$ _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. 通过这种方式发送数据,请求的Content-Type将为“ multipart / form-data”,其中$ _FILES上具有blob,图像和一般文件,而$ _POST上具有其余文件,因此“ php:// input ”不会有帮助。

<?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 : 还要记住,以这种方式上传Blob时,如果您不打算在服务器端生成文件名(在大多数情况下可能应该这样做),并且希望由上传者指定一个特定的名称,它们将获得一个随机名称。 ,则可以将其与FormData一起传递:

formData.append('blobImage',blob, "MyBloBName");

如果您在jQuery Ajax调用中将contentType: false设置为,则仍可以将相同的代码与formData一起formData ,然后通过$_FILES['blobImage']访问服务器上的文件

The problem is that $_REQUEST, and therefore $_GET and $_POST objects have a limitation to the number of characters available to them. 问题是$ _REQUEST以及$ _GET和$ _POST对象对它们可用的字符数有限制。

post_max_size

in PHP.ini controls the maximum size of post. PHP.ini中的控件控制帖子的最大大小。

Browsers and their implementations of $_GET control the limit of a $_GET request. 浏览器及其$ _GET的实现控制$ _GET请求的限制。 As it appears in their URL bar. 出现在其网址栏中。 For example IE9's limit is 2000 characters so if your blob ends up as anything more than 2000 characters in the $_GET Request. 例如,IE9的限制为2000个字符,因此,如果$ _GET请求中的blob最终超过2000个字符,则为IE9。 The general consensus is that $_GET requests should be much less than 255 bytes. 普遍的共识是$ _GET请求应该少于255个字节。 And if you approach this limit be careful because older browsers and protocols are completely unprepared for this. 而且,如果您接近此限制,请小心,因为较旧的浏览器和协议完全没有为此做好准备。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM