问题:在上传大图像文件时,我认识到在我的AWS server
上传1gb memory
使用它的全部容量时,它会上升到932 mb
使用,这会导致进程崩溃。我正在以DataURI的形式保存该图像,然后我在某处读到以blob
的形式保存它可以解决我的问题。所以我想将blob附加到formData并发送到服务器,这就是我提出这个问题的原因。然而,如果关于相同问题的任何其他建议以在存储器方面更有效地保存图像,将不胜感激。
原因
我想以blob
的形式将图像发送到服务器端。
我做了什么
我现在有一个dataURI
,我已经转换成blob
。此外,我将blob附加到formData
并尝试使用ajax将其发送到服务器端/ php。
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'];
?>
错误
我在控制台中收到null,我也查看了标题formData
的标题
正如你所看到的,$_POST
显示blob但是$_POST['blobImage']
显示为null。
解决方案我要求:
我不是那么快php
所以我不确定我是否以正确的方式发送blob
或接收它。
我已尽我所能为实现自己的动机而努力。
感谢社区的帮助。
在jQuery Ajax调用上添加以下三个属性,它们是blob所必需的:
cache: false,
contentType: false,
processData: false
然后不要在Ajax Call的data属性中使用formData,只需添加创建的blob即可。还添加一个小的渲染回调(除了你已经使用的console.log之外)来打印Image。你的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://输入”使用而言。它返回请求标题之后的所有原始数据,并且它不关心它们的类型,这在大多数情况下非常方便。而$ _POST仅包装已使用以下内容类型传递的数据:
如果您确实想使用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”,它将在$ _FILES上有blob,图像和一般文件,其余在$ _POST上,所以“php:// input”没有用。
<?php
var_dump($_FILES);
?>
另外请记住,当以这种方式上传blob时,如果您不打算在服务器端生成文件名(在大多数情况下您可能应该这样做),并且需要上传者指定的特定名称,那么它们将获得一个随机名称,然后你可以将它与FormData一起传递,如:
formData.append('blobImage',blob, "MyBloBName");
如果你在jQuery Ajax调用中设置contentType: false
,你仍然可以使用与formData
相同的代码,然后通过$_FILES['blobImage']
访问服务器上的文件
问题是$ _REQUEST,因此$ _GET和$ _POST对象对它们可用的字符数有限制。
post_max_size
在PHP.ini中控制post的最大大小。
浏览器及其$ _GET的实现控制$ _GET请求的限制。因为它出现在他们的URL栏中。例如,IE9的限制是2000个字符,所以如果你的blob最终在$ _GET请求中超过2000个字符。普遍的共识是$ _GET请求应该远小于255个字节。如果你接近这个限制要小心,因为旧的浏览器和协议完全没有准备好。