Javascript 使用AJAX将base64图像作为类似文件输入并使用文件名上传

Javascript 使用AJAX将base64图像作为类似文件输入并使用文件名上传,javascript,jquery,ajax,Javascript,Jquery,Ajax,在服务器端,我有一个SpringMVC(JAVA)项目,它使用MultipartFile @RequestMapping(value = { "/uploadImg/**" }, method = RequestMethod.POST) public void uploadImg(Model model, HttpServletRequest request,HttpServletResponse response,MultipartFile file ) { S

在服务器端,我有一个SpringMVC(JAVA)项目,它使用
MultipartFile

@RequestMapping(value = { "/uploadImg/**" }, method = RequestMethod.POST)
public void uploadImg(Model model, HttpServletRequest request,HttpServletResponse response,MultipartFile file ) 
{
     String originalFileName = file.getOriginalFilename();
     //some cases on based on file name and storing the file into the server
}
以前,我使用
上传文件。但现在我有了base64格式的图像数据,并希望使用AJAX将其上传到相同的请求映射

我遇到了这一点,还有很多这样的解决方案。但所有的都只是上传文件数据,但在我的例子中,我想上传带有数据和名称的图像,因为在服务器端,一些逻辑是基于文件名编写的

一个选项可能是,在参数中发送图像数据,在另一个参数中发送文件名,但我无权访问(或者说我不能更改)服务器端代码来执行此操作


那么,使用AJAX如何上传base64图像数据和文件名呢?

我用PHP服务器测试了以下代码。我没有访问SpringMVC服务器的权限,但是这两个服务器的JS代码应该是相同的。代码主要基于本文:

//我缩短了base64数据以保持此答案的简短。有关完整数据,请参阅链接文章
让ImageURL=“data:image/gif;base64,R0lGODlhPQBEAPeoAJosM…”;
let block=ImageURL.split(“;”);
让contentType=block[0]。拆分(“:”[1];//在本例中为“image/gif”
让realData=block[1]。拆分(“,”[1];//在本例中,“R0lGODlhPQBEAPeoAJosM…”
设blob=b64toBlob(realData,contentType);
设formDataToUpload=newformdata();
formDataToUpload.append(“image”,blob,“filename.gif”);//您可以在这里设置文件名
$.ajax({
url:“/upload.php”,
数据:formDataToUpload,
键入:“POST”,
contentType:false,
processData:false
});
/**
*根据数据和内容类型转换Blob中的base64字符串。
*
*@param b64Data{String}纯base64字符串,不带contentType
*@param contentType{String}文件的内容类型,即(image/jpeg-image/png-text/plain)
*@param sliceSize{int}sliceSize处理字节字符
*@见http://stackoverflow.com/questions/16245767/creating-a-blob-from-a-base64-string-in-javascript
*@return Blob
*/
函数b64toBlob(b64Data、contentType、sliceSize){
contentType=contentType | |“”;
切片大小=切片大小| | 512;
let byteCharacters=atob(b64Data);
let ByteArray=[];
for(让offset=0;offset
最好是更改生成此base64版本的内容,使其直接返回Blob

如果没有这样的选项,您仍然可以自己将base64字符串转换为Blob。 拥有Blob后,您就可以使用
XMLHttpRequest
fetch
将其发布到服务器上,就像html
一样,这要感谢

//作为base64的1x1px png图像
const b64=“ivborw0kgoaaaansuhueugaaaaaaaaaaabababababababababaaafaffcsjaaaduleqvqimwngygbgaaabqhabh6fo1aaabjru5erkjggg=”;
//将其设置为用户的“name”属性
const上一个文件的\u name\u\u\u input=“file”;
//将其设置为所需的任何文件名
const the_file_name=“pixel.png”;
const blob=新blob([base64ToArrayBuffer(b64)]);
const form=new FormData();
append(上一个文件输入的文件名,blob,文件名);
console.log(…表单);
/*由于无法在StackSnippets中工作,上载将被注释
//对于现代浏览器,可以使用fetchapi
fetch(您的服务器URL,{method:“post”,body:form});
//或者对于较旧的浏览器
const xhr=new XMLHttpRequest();
打开(“POST”,即您的服务器URL);
发送(表格);
*/
函数base64到ArrayBuffer(base64){
const binary_str=atob(base64);
const arr=新的Uint8Array(base64.length);

对于(让i=0;i可能这有帮助:@ahendwh2不,这没有帮助。正如我说的,它将在两个请求参数中发送文件数据和文件名。这将需要更改服务器代码。对吗?我写评论时没有太多时间。我在下面发布了完整的答案
// I've shortend the base64 data to keep this answer short. See the linked article for the complete data
let ImageURL = "data:image/gif;base64,R0lGODlhPQBEAPeoAJosM....";

let block = ImageURL.split(";");
let contentType = block[0].split(":")[1];// In this case "image/gif"
let realData = block[1].split(",")[1];// In this case "R0lGODlhPQBEAPeoAJosM...."

let blob = b64toBlob(realData, contentType);

let formDataToUpload = new FormData();
formDataToUpload.append("image", blob, 'filename.gif'); // Here you can set the filename

$.ajax({
    url: '/upload.php',
    data: formDataToUpload,
    type: 'POST',
    contentType: false,
    processData: false
});

/**
 * Convert a base64 string in a Blob according to the data and contentType.
 *
 * @param b64Data {String} Pure base64 string without contentType
 * @param contentType {String} the content type of the file i.e (image/jpeg - image/png - text/plain)
 * @param sliceSize {int} SliceSize to process the byteCharacters
 * @see http://stackoverflow.com/questions/16245767/creating-a-blob-from-a-base64-string-in-javascript
 * @return Blob
 */
function b64toBlob(b64Data, contentType, sliceSize) {
    contentType = contentType || '';
    sliceSize = sliceSize || 512;

    let byteCharacters = atob(b64Data);
    let byteArrays = [];

    for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
        let slice = byteCharacters.slice(offset, offset + sliceSize);

        let byteNumbers = new Array(slice.length);

        for (let i = 0; i < slice.length; i++) {
            byteNumbers[i] = slice.charCodeAt(i);
        }

        let byteArray = new Uint8Array(byteNumbers);

        byteArrays.push(byteArray);
    }

    return new Blob(byteArrays, {type: contentType});
}