Javascript 使用 Ajax 上传 base64 图像
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/34779799/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Upload base64 image with Ajax
提问by Nitseg
My client is offering the user to pick a picture, crop and resize it and then display it (in a <img>
DOM element).
If the picture is fine, the user can upload it to the server so it can be saved.
我的客户让用户选择一张图片,裁剪并调整它的大小,然后显示它(在<img>
DOM 元素中)。
如果图片没问题,用户可以将其上传到服务器以便保存。
I would like to do the upload thanks to an Ajax request.
由于 Ajax 请求,我想上传。
I found tons of examples on the internet to upload the original imageretrieved from the client PC. For instance:
我在互联网上找到了大量示例来上传从客户端 PC 检索到的原始图像。例如:
$( '#my-form' )
.submit( function( e ) {
$.ajax( {
url: 'http://host.com/action/',
type: 'POST',
data: new FormData( this ),
processData: false,
contentType: false
} );
e.preventDefault();
} );
This works properly if I decide to upload the picture retrieved through the form input.
如果我决定上传通过表单输入检索到的图片,这将正常工作。
In my case I want to upload the modified picture(saved in a <img>
element) instead of the original one.
This picture is stored as a base64 picture (For information: I used the croppie.js library to generate the image).
就我而言,我想上传修改后的图片(保存在<img>
元素中)而不是原始图片。
这张图片存储为base64图片(参考:我使用croppie.js库来生成图片)。
I don't know how to upload this picture with Ajax.
我不知道如何用 Ajax 上传这张图片。
I tried to upload it as a regular parameter but on the server side the img is an empty string:
我试图将它作为常规参数上传,但在服务器端,img 是一个空字符串:
var url = 'http://host.com/action/';
var data = {};
data.img = $('img#generated-image').attr('src');
$.ajax({url: url, type: "POST", data: data})
.done(function(e){
// Do something
});
// RESULTS in a empty data.img on the server side.
My problem being the server having an empty string when retrieving the "img" parameter. I suspect the image is maybe too big to be passed to the server or some other issues that I don't understand... .
我的问题是服务器在检索“img”参数时有一个空字符串。我怀疑图像可能太大而无法传递到服务器或其他一些我不明白的问题......
So I'm wondering what is the proper way to send a base64 image to the serverusing an Ajax request WITHOUTusing a form.
所以我想知道使用 Ajax 请求而不使用表单将 base64 图像发送到服务器的正确方法是什么。
Thanks for your help.
谢谢你的帮助。
EDIT
编辑
Seems to be an xmlHTTP POST parameter size issue. I tried to reduce the number of characters of the string representation of the image and the server is now able to retrieve it.
似乎是 xmlHTTP POST 参数大小问题。我试图减少图像字符串表示的字符数,服务器现在可以检索它。
EDIT2
编辑2
post_max_size is set to 8M in the php.ini file wheras the picture size is only 24K. So the problem is not there.
I'm using PHP with the Symfony2 framework.
Maybe a limitation from Symfony2.
php.ini 文件中 post_max_size 设置为 8M,而图片大小只有 24K。所以问题不存在。
我在 Symfony2 框架中使用 PHP。
可能是 Symfony2 的限制。
回答by Nitseg
I finally decided to convert the base64 image to a Blob so it can be sent via an Ajax request with the formData object as follows. It saves upload bandwidth (base64 takes 33% more bits than its binary equivalent) and I couldn't find the reason for no transmission of base64 parameter (due to size limitation somewhere for sure).
我最终决定将 base64 图像转换为 Blob,以便它可以通过带有 formData 对象的 Ajax 请求发送,如下所示。它节省了上传带宽(base64 比其二进制等价物多占用 33% 位)并且我找不到不传输 base64 参数的原因(肯定是由于某处的大小限制)。
The base64ToBlob function is based on this answer to another question.
base64ToBlob 函数基于此对另一个问题的回答。
function base64ToBlob(base64, mime)
{
mime = mime || '';
var sliceSize = 1024;
var byteChars = window.atob(base64);
var byteArrays = [];
for (var offset = 0, len = byteChars.length; offset < len; offset += sliceSize) {
var slice = byteChars.slice(offset, offset + sliceSize);
var byteNumbers = new Array(slice.length);
for (var i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i);
}
var byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
}
return new Blob(byteArrays, {type: mime});
}
My JS code:
我的JS代码:
var url = "url/action";
var image = $('#image-id').attr('src');
var base64ImageContent = image.replace(/^data:image\/(png|jpg);base64,/, "");
var blob = base64ToBlob(base64ImageContent, 'image/png');
var formData = new FormData();
formData.append('picture', blob);
$.ajax({
url: url,
type: "POST",
cache: false,
contentType: false,
processData: false,
data: formData})
.done(function(e){
alert('done!');
});
In Symfony2 I can retrieve the image thanks to:
在 Symfony2 中,由于以下原因,我可以检索图像:
$picture = $request->files->get('picture');
回答by omt66
Nitseg's answer works nicely. Also, I wanted to add the following lines if you must use auth token in your ajax call. Again, take a look at Nitseg's answer for more details first.
Nitseg 的回答效果很好。另外,如果您必须在 ajax 调用中使用身份验证令牌,我想添加以下几行。同样,请先查看 Nitseg 的回答以了解更多详细信息。
var formData = new FormData();
var token = "<YOUR-TOKEN-HERE>";
formData.append("uploadfile", mediaBlob);
jQuery.ajax({
url: url,
type: "POST",
cache: false,
contentType: false,
processData: false,
data: formData,
beforeSend: function (xhr){
xhr.setRequestHeader("Authorization", "Bearer " + token);
}
})
.done((e) => {
// It is done.
})
.fail((e) => {
// Report that there is a problem!
});