Spring Boot 如何上传大文件?骚操作~(1)

《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门,即可获取!

// 获取图片的编码,然后将图片当做是一个很长的字符串进行传递

vardata= canvas.toDataURL( “image/jpeg”, 0.5);

在服务端需要做的事情也比较简单,首先解码base64,然后保存图片即可

i m g D a t a   =   imgData =  imgData = _REQUEST[ ‘imgData’];

b a s e 64   =   e x p l o d e (   ′ , ′ ,   base64 = explode( ',',  base64 = explode( ,, imgData)[ 1];

i m g   =   b a s e 6 4 d e c o d e ( img = base64_decode( img = base64decode(base64);

$url = ‘./test.jpg’;

if(file_put_contents( u r l ,   url,  url, img)) {

exit(json_encode( array(

url => $url

)));

}

base64编码的缺点在于其体积比原图片更大(因为Base64将三个字节转化成四个字节,因此编码后的文本,会比原文本大出三分之一左右),对于体积很大的文件来说,上传和解析的时间会明显增加。

更多关于base64的知识,可以参考Base64笔记。

除了进行base64编码,还可以在前端直接读取文件内容后以二进制格式上传

// 读取二进制文件

functionreadBinary(text){

vardata = newArrayBuffer(text.length);

varui8a = newUint8Array(data, 0);

for( vari = 0; i < text.length; i++){

ui8a[i] = (text.charCodeAt(i) & 0xff);

}

console.log(ui8a)

}

varreader = newFileReader;

reader. = function{

readBinary( this.result) // 读取result或直接上传

}

// 把从input里读取的文件内容,放到fileReader的result字段里

reader.readAsBinaryString(file);

formData异步上传

FormData对象主要用来组装一组用 发送请求的键/值对,可以更加灵活地发送Ajax请求。可以使用FormData来模拟表单提交。

letfiles = e.target.files // 获取input的file对象

letformData = newFormData;

formData.append( ‘file’, file);

axios.post(url, formData);

服务端处理方式与直接form表单请求基本相同。

iframe无刷新页面

在低版本的浏览器(如IE)上,xhr是不支持直接上传formdata的,因此只能用form来上传文件,而form提交本身会进行页面跳转,这是因为form表单的target属性导致的,其取值有

_self,默认值,在相同的窗口中打开响应页面

_blank,在新窗口打开

_parent,在父窗口打开

_top,在最顶层的窗口打开

framename,在指定名字的iframe中打开

如果需要让用户体验异步上传文件的感觉,可以通过framename指定iframe来实现。把form的target属性设置为一个看不见的iframe,那么返回的数据就会被这个iframe接受,因此只有该iframe会被刷新,至于返回结果,也可以通过解析这个iframe内的文本来获取。

functionupload{

varnow = + newDate

varid = ‘frame’+ now

(   " b o d y " ) . a p p e n d (   ‘ < i f r a m e   s t y l e = " d i s p l a y : n o n e ; "   n a m e = " ( "body").append( `<iframe style="display:none;" name=" ( "body").append( ‘<iframe style="display:none;name="{id}" id=“${id}” />`);

var f o r m   =   form =  form = ( “#myForm”)

$form.attr({

“action”: ‘/index.php’,

“method”: “post”,

“enctype”: “multipart/form-data”,

“encoding”: “multipart/form-data”,

“target”: id

}).submit

$( “#”+id).on( “load”, function{

varcontent = $( this).contents.find( “body”).text

try{

vardata = JSON.parse(content)

} catch(e){

console.log(e)

}

})

}

大文件上传

现在来看看在上面提到的几种上传方式中实现大文件上传会遇见的超时问题,

表单上传和iframe无刷新页面上传,实际上都是通过form标签进行上传文件,这种方式将整个请求完全交给浏览器处理,当上传大文件时,可能会遇见请求超时的情形

通过fromData,其实际也是在xhr中封装一组请求参数,用来模拟表单请求,无法避免大文件上传超时的问题

编码上传,我们可以比较灵活地控制上传的内容

大文件上传最主要的问题就在于:在同一个请求中,要上传大量的数据,导致整个过程会比较漫长,且失败后需要重头开始上传。试想,如果我们将这个请求拆分成多个请求,每个请求的时间就会缩短,且如果某个请求失败,只需要重新发送这一次请求即可,无需从头开始,这样是否可以解决大文件上传的问题呢?

综合上面的问题,看来大文件上传需要实现下面几个需求

支持拆分上传请求(即切片)

支持断点续传

支持显示上传进度和暂停上传

接下来让我们依次实现这些功能,看起来最主要的功能应该就是切片了。

文件切片

参考:大文件切割上传

编码方式上传中,在前端我们只要先获取文件的二进制内容,然后对其内容进行拆分,最后将每个切片上传到服务端即可。

在Java中,文件FIle对象是Blob对象的子类,Blob对象包含一个重要的方法slice,通过这个方法,我们就可以对二进制文件进行拆分。

下面是一个拆分文件的示例,对于up6来说开发者不需要关心拆分的细节,由控件帮助实现,开发者只需要关心业务逻辑即可。

控件上传的时候会为每一个文件块数据添加相关的信息,开发者在服务端接收到数据后可以自已进行处理。

最后

image.png

《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门,即可获取!
xcGljLmNuL21tYml6X3BuZy8za01acHBRYTV6RGFiSVFzbXZsOWt3Rnp0MzlSRXB3dmtjbVdrQWoxazE3S2Z3SHNnZ3hmODZWWU9iNk1wRUd6Wnh0aDdZNTVvSVRyZWJLUHNEWmljNEEvNjQw?x-oss-process=image/format,png)

最后

[外链图片转存中…(img-Oqk0iPQw-1714655705291)]

《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门,即可获取!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值