>  기사  >  웹 프론트엔드  >  tp5+layui를 사용한 대용량 파일 업로드 소개

tp5+layui를 사용한 대용량 파일 업로드 소개

尚
앞으로
2019-12-16 17:28:294772검색

tp5+layui를 사용한 대용량 파일 업로드 소개

파일 업로드 크기를 변경하려면 먼저 일부 구성 정보를 기록해 주세요.

php.ini 열기#🎜 ###### 🎜🎜#FILE_UPLOADS = ON // http를 통해 파일의 스위치를 업로드하고 ##의 경로를 열 수 있는지 여부 🎜🎜UPLOAD_TMP_DIR // 임시 파일

🎜🎜

upload_max_filesize 20M //업로드 가능한 최대 파일 크기

post_max_size 22M //POST 양식을 통해 업로드할 수 있는 크기

max_execution_time 600 / /단일 PHP 페이지를 실행할 수 있는 최대 시간

max_input_time                                                                       단일 PHP 페이지가 데이터를 수신하는 데 필요한 최대 시간, 기본값은 최대 메모리 60초, 기본값은 8M

위 구성을 변경하여 허용되는 파일 업로드 크기를 조정할 수 있습니다. (일부는 서버의 일부 구성을 조정해야 함)

Additional: 413 error 서버가 nginx인 경우 nginx_conf 구성에서 client_max_body_size 24M을 변경하여 전송된 패킷을 수신하는 최대값을 설정해야 합니다. 클라이언트에 의해. http에 넣고, 서버를 다시 시작하고, 다시 시작을 사용하고, 다시 로드를 사용하지 마세요.

그럼 파일 분할 업로드를 시작해 보세요.

파일은 HTML의 파일 입력 태그를 통해 업로드됩니다. H5를 통해 새로운 객체 FileReader. 문자 그대로의 의미와 마찬가지로 FileRaeder 개체는 로컬 파일을 읽는 개체입니다. FileReader 개체는 로컬 파일을 읽고 base64 인코딩으로 반환할 수 있습니다. (FileReader 개체 사용에 대한 구체적인 내용은 Baidu를 참조하거나 매우 구체적인 다음 블로그 게시물을 읽어보십시오. 시도

입력 파일 태그를 통해 파일 선택

# 🎜🎜#FileReader 객체를 사용하여 파일 읽기

파일의 base64 인코딩을 ajax를 통해 비동기적으로 전송합니다. 이를 수신한 후 서버는 인코딩을 디코딩하여 파일에 저장합니다. 테스트 결과는 실패합니다. 파일이 너무 크면 인코딩 길이가 길어집니다. ajax를 통해 비동기적으로 제출되는 최대 매개변수 수는 8000바이트입니다.

두 번째 시도는 얻은 base64 인코딩을 기반으로 분할하는 것입니다.

얻은 base64 인코딩 문자열을 여러 부분으로 나누고 번호를 매긴 후 루프에서 ajax를 호출하여 전송합니다.

데이터를 받은 후 서버는 이름

작은 파일을 모두 받은 후 백그라운드 메서드를 호출하여 작은 파일을 병합합니다.

업로드된 파일이 1G를 초과했을 때 테스트 결과가 실패했습니다. 브라우저가 충돌했습니다. 파일을 읽을 때 파일이 너무 크고 일회성 읽기에서 반환된 base64 인코딩이 너무 커서 페이지가 충돌했습니다

#🎜🎜. # 이를 바탕으로 한 번에 너무 큰 파일을 읽어서 발생하는 페이지 충돌을 피하기 위해 파일을 읽는 과정에서 일괄적으로 읽어서 인코딩을 얻고 싶습니다. .slice() 파일을 덩어리로 나누어 일괄 읽기를 구현합니다. 그리고 일괄 업로드를 서버에 비동기적으로 전송합니다

서버가 디코딩 및 파일 저장을 위한 데이터를 수신합니다

테스트가 성공적으로 완료되었으며 테스트는 거의 4G의 파일을 업로드했습니다 #🎜 🎜#

( 파일이 분할되어 있기 때문에 대용량 파일을 업로드할 때 대량의 ajax 요청이 시작되어 동시성이 많아지고 이로 인해 페이지가 다시 충돌할 수 있으므로 시차를 두고 요청을 사용합니다. )

특정 구현 코드

다음 코드 게시

프론트 엔드 프레임워크:layui

백엔드 프레임워크: tp5

페이지 코드:

<div class="layui-form-item">
    <label class="layui-form-label">视频上传</label>
    <div class="layui-input-block layui-upload-video-btn">
        <ul>
            <li class="img-upload">
                <label></label>
                <input type="file" class="video-upload-file layui-upload-video-file-btn" name="file"/>
                <video width="320" height="240" controls style="display: none">
                    <source src="" type="video/mp4">
                    <source src="" type="video/ogg">
                    您的浏览器不支持Video标签。
                </video>
                <span style="display: none">X</span>
                <input type="hidden" class="video-link-id" name="video_link_id" value="">
            </li>
            <li>//视频上传会比较久(上传完会有提示)</li>
        </ul>
    </div>
</div>

js 코드:

$(&#39;.video-upload-file&#39;).on(&#39;change&#39;,function(){
        layer.msg(&#39;正在提交视频......&#39;);
        //隐藏按钮,显示进度条
        $(&#39;.layui-upload-video&#39;).hide();
        $(&#39;.layui-progress-ads&#39;).show();
        var loads_video = layer.load(2,{shade: [0.2, &#39;#3a3535&#39;]});      //产生加载圈,禁止用户其他操作
        var thisFile = $(this);
        var reader=new FileReader();
        var file_size = this.files[0].size;     //文件大小
        var limit = 8388608;        //每次读取文件的大小
        // var limit = 1048000;        //每次读取文件的大小
        var up_count = Math.ceil(file_size/limit);     //总上传次数
        var type = this.files[0].type.substr(this.files[0].type.indexOf(&#39;/&#39;)+1);   //文件类型
        var success_num = 0;        //用于存放上传成功的数据的id
        var check = 1;             //防止多次合并
        console.log(&#39;文件大小:&#39;+this.files[0].size);
        console.log(&#39;文件类型:&#39;+type);
        console.log(&#39;分割上传次数:&#39;+up_count);
        //分段读取文件
        readFile(this.files[0], 0, limit);
        function readFile(file, num, limit){
            // console.log(&#39;第&#39;+num+&#39;次:&#39;+num*limit);
            reader.readAsDataURL(file.slice(num*limit, (num+1)*limit));
            reader.onload = function(e){
                console.log(reader.result.length);
                console.log(reader.result);
                //异步base64的数据传输到服务器
                ajax_way(reader.result, name, num+1, thisFile);
                if((num+1)*limit <= file_size){
                    readFile(file, num+1, limit);
                }
            }
        }
        function ajax_way(data,name,num, thisFile){
            //避免一次性生成太多的请求
            if(num+1 > 60){
                // console.log(&#39;等待两秒&#39;);
                sleep(6000);
                // console.log(&#39;等待结束&#39;);
            }
            $.ajax({
                url: "<?= url(&#39;admin/video/up_mfile&#39;);?>",
                type: "POST",
                data: {video:data,name:name,num:num},
                // async:false,      //是否采用同步,串行发送请求
                success: function (data) {
                    if(data.code == 1){
                        //上传成功,成功次数加一
                        success_num++;
                        console.log(num+&#39;完成&#39;);
                        console.log(&#39;已完成:&#39;+success_num+&#39;/&#39;+up_count);
                        //计算完成的百分比
                        var precentage = Math.ceil((success_num/up_count)*100);
                        //更改进度条显示
                        $(&#39;.layui-progress-ads-btn&#39;).attr(&#39;lay-percent&#39;, precentage+&#39;%&#39;);
                        $(&#39;.layui-progress-ads-btn&#39;).css(&#39;width&#39;, precentage+&#39;%&#39;);
                        $(&#39;.layui-progress-text&#39;).html(precentage+&#39;%&#39;);
                        //如果分割文件都上传了则调用接口合并文件
                        if(success_num == up_count && check == 1){
                            check = 0;
                            success_num = 0;
                            merge_mfile(name, up_count, thisFile, type);
                        }
                    }
                },
                error:function(e){
                    console.log(&#39;出错了:&#39;+num);
                    //传输出错则重新上传
                    ajax_way(data, name, num, thisFile);
                }
            });
        }

        //合并文件
        function merge_mfile(name, count, thisFile, type){
            $.ajax({
                url:"<?= url(&#39;admin/video/merge_mfile&#39;);?>",
                data:{name:name, count:count, type:type},
                type:"POST",
                success:function(data){
                    if (data.code==1){
                        layer.close(loads_video);
                        layer.msg(&#39;视频提交成功&#39;);
                        thisFile.siblings(&#39;.video-link-id&#39;).val(data.data);
                    }else{
                        layer.msg(&#39;视频提交异常请重新提交&#39;);
                        //显示按钮,隐藏进度条
                        $(&#39;.layui-upload-video&#39;).show();
                        $(&#39;.layui-progress-ads&#39;).hide();
                        //将进度条置零
                        $(&#39;.layui-progress-ads-btn&#39;).attr(&#39;lay-percent&#39;, &#39;0%&#39;);
                        $(&#39;.layui-progress-ads-btn&#39;).css(&#39;width&#39;, &#39;0%&#39;);
                        $(&#39;.layui-progress-text&#39;).html(&#39;0%&#39;);
                        //清空已选中的文件
                        var file = $(".layui-upload-video-file-btn");
                        file.after(file.clone().val(""));
                        file.remove();
                    }
                }
            })
        }
        function sleep(n) { //n表示的毫秒数
            var start = new Date().getTime();
            while (true) if (new Date().getTime() - start > n) break;
        }
        return false;
    });

layui에 대한 더 많은 지식을 알고 싶다면 주목해주세요.

layui 사용법 튜토리얼

위 내용은 tp5+layui를 사용한 대용량 파일 업로드 소개의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 cnblogs.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제