当我们把base64图片上传到服务器时,您可能想到的是先将此文件作为base64图像字符串的形式传到服务器端,然后在服务器端将此其转换为一个图像文件,但是如果每个请求都这样做的话,无疑会极大的增加服务器端的工作。
因此在本文中,我们将学习如何将Base64字符串转换为Blob图像二进制的形式,然后使用jquery ajax异步上传到服务器中,此方法相当于用户做了一个Form表单提交了file文件输入框中的文件。
现在我们先开始将base64图片转换为图像文件Blob二进制流,使用javascript将base64图片转换为file文件的方式如下,该方法为自定义方法:
/**
参数一:base64字符串数据
参数二:base64文件类型
参数三:处理字符串大小
*/
function b64toBlob(b64Data, contentType, sliceSize) {
contentType = contentType || '';
sliceSize = sliceSize || 512;
var byteCharacters = atob(b64Data);
var byteArrays = [];
for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) {
var slice = byteCharacters.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);
}
var blob = new Blob(byteArrays, {type: contentType});
return blob;
}我们使用一个Button按钮,使用Post异步请求提交Form表单,后面会有阻止Form表单直接提交的方法,之所以把Button放在<form>标签内部,后面会给出理由,代码如下:
<form id="myAwesomeForm" method="post" action="/php-code-that-handles-fileupload.php"> <!-- 可以输入一个文件名之后提交 --> <input type="text" id="filename" name="filename" /> <!-- Submit提交按钮 --> <input type="submit" id="submitButton" name="submitButton" /> </form>
下面是调用前面定义的b64toBlob()方法,将base64图片转化为图像文件的blob字节流,然后封装到javascript的FormData()对象中,并作为ajax的data数据提交到后台,代码如下:
// Get the form element withot jQuery
var form = document.getElementById("myAwesomeForm");
//base64图片,由于数据过多,后面部分已经省略
var ImageURL = "data:image/gif;base64,R0lGODlhPQBEAPeoAJosM//AwO/AwHVYZ/z595kzAP/s7P+goOXMv8+fhw/v739/f+8PD98fH/8mJl+fn/9ZWb8/PzWlwv....";
// 切割base64字符串,获取图片类型与图片实体数据
var block = ImageURL.split(";");
// 获取图片类型
var contentType = block[0].split(":")[1];// 图像类型 "image/gif"
// 获取base64图片内容实体
var realData = block[1].split(",")[1];// 图像数据实体部分 "R0lGODlhPQBEAPeoAJosM...."
// 转化成blob字节流用于上传
var blob = b64toBlob(realData, contentType);
// 创建FormData,将"image"作为后台的name参数,后台会用一个为"image" 的name变量来接收数据
var formDataToUpload = new FormData(form);
//将blob添加到name属性
formDataToUpload.append("image", blob);现在FormData中有了一个文件,我们可以使用jquery ajax来异步提交该文件了,代码如下:
//为什么上面的form表单中有了一个action="xxx"了,此处url还要输入一个网址呢?请稍后看最后面就明白!!!
$.ajax({
url:"/php-code-that-handles-fileupload.php",
data: formDataToUpload,// Add as Data the Previously create formData
type:"POST",
contentType:false,
processData:false,
cache:false,
dataType:"json", // Change this according to your response from the server.
error:function(err){
console.error(err);
},
success:function(data){
console.log(data);
},
complete:function(){
console.log("Request finished.");
}
});完整的代码请看下方:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Base64 string to a file in form</title>
</head>
<body>
<form id="myAwesomeForm" method="post" action="endpoint.php">
<input type="text" id="filename" name="filename" /> <!-- Filename -->
<input type="submit" id="submitButton" name="submitButton" /> <!-- Submit -->
</form>
<script>
function b64toBlob(b64Data, contentType, sliceSize) {
contentType = contentType || '';
sliceSize = sliceSize || 512;
var byteCharacters = atob(b64Data);
var byteArrays = [];
for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) {
var slice = byteCharacters.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);
}
var blob = new Blob(byteArrays, {type: contentType});
return blob;
}
$("#myAwesomeForm").submit(function(e){
//阻止Form表单直接被提交
e.preventDefault();
//然后使用ajax文件提交
appendFileAndSubmit();
});
function appendFileAndSubmit(){
// Get the form
var form = document.getElementById("myAwesomeForm");
var ImageURL = "data:image/gif;base64,R0lGODlhPQBEAPeoAJosM//AwO/AwHVYZ/z595kzAP/s7P+goOXMv8+fhw/v739/f+8PD98fH/8mJl+fn/9ZWb8/PzWlwv....";
var block = ImageURL.split(";");
// Get the content type
var contentType = block[0].split(":")[1];// In this case "image/gif"
// get the real base64 content of the file
var realData = block[1].split(",")[1];// In this case "R0lGODlhPQBEAPeoAJosM...."
// Convert to blob
var blob = b64toBlob(realData, contentType);
// 创建FormData对象并添加一个file文件
var fd = new FormData(form);
fd.append("image", blob);
// Submit Form and upload file
$.ajax({
url:"endpoint.php", //后台接收上传的文件
data: fd, //提交formData字节流的数据
type:"POST",
contentType:false,
processData:false,
cache:false,
dataType:"json",
error:function(err){
console.error(err);
},
success:function(data){
console.log(data);
},
complete:function(){
console.log("Request finished.");
}
});
}
</script>
</body>
</html>下面来看php后台大概是如何接收的,如果是Java web项目大致也一样,就是使用(MultipartFile image)这个image属性来接收参数即可,先看看php后台服务器的大致写法吧!
<?php
// Important to use these statemenets, the json response is optional for our response.
use Symfony\Component\HttpFoundation\Request;
public function retrieveAction(Request $request){
// retrieve the file with the name given in the form.
// do var_dump($request->files->all()); if you need to know if the file is being uploaded.
$file = $request->files->get('image');
$nameInTextInput = $request->request->get("filename");
}说明:项目的语言等可能和你用的不一样,但是思想是一致的,就是将base64图片转换为图像文件,然后使用form表单提交或者ajax提交即可。