> 웹 프론트엔드 > H5 튜토리얼 > H5를 사용하여 사진을 업로드하는 방법

H5를 사용하여 사진을 업로드하는 방법

php中世界最好的语言
풀어 주다: 2018-06-04 11:20:00
원래의
8587명이 탐색했습니다.

이번에는 H5를 사용하여 이미지를 업로드하는 방법과 H5를 사용하여 이미지를 업로드하는 Notes가 무엇인지 보여드리겠습니다. 다음은 실제 사례입니다.

저는 며칠 전에 프로젝트를 진행했는데, 모듈 중 하나가 이미지를 서버에 업로드하는 것과 관련이 있었습니다. 오늘 시간을 내어 정리해보니 정리할수록 관련 지식 포인트가 많아지는 것을 발견했습니다. 다음 예는 바이두의 검색 지도를 참고한 것입니다.

지식 포인트: 입력 파일, base64, FileReader, 캔버스 압축, blob, btoa 인코딩 및 atob 디코딩, FormData.

html dom 노드:

<input type="file">
로그인 후 복사

기본적으로 파일을 선택할 수 있습니다. 여러 장의 사진을 업로드해야 합니다. multiple="true" 속성을 추가할 수 있습니다. 일반적으로 기본 스타일을 숨기려면 opacity:0을 사용하고 해당 스타일을 다시 작성합니다.

1. 객체 생성

var fileReader = new FileReader();

2 브라우저가 호환되는지 확인 - ie8에서는 지원되지 않음

if( window.FileReader )

3. 상태 상수

상수 이름 Value Description
EMPTY 0 Start 파일 읽기
LOADING 1 파일 읽기
DONE 2 파일 읽기 완료

아래 예에서는 현재 상태 별도로 읽을 수 있습니다.

4.속성

속성 이름 Description
error 오류가 발생했습니다
readyState current fileReader 객체의 상태는 위의 상태 상수 중 하나입니다
result 콘텐츠 읽기

5. 메서드

6을 나타냅니다.
메서드 이름 Parameters Description
abort 없음 읽기 중단, LOADING 상태가 아닐 때 호출됨 예외가 발생합니다
readAsArrayBuffer blob/file 이 배열로 읽혀지고, 읽은 콘텐츠의 결과에 ArrayBuffer 객체가 있습니다
readAsBinaryString blob/file 은 바이너리로 읽혀지며 결과적으로 읽은 파일의 원본 바이너리가 있습니다
readAsDataUrl blob/file 읽기 as dataUrl, in 결과에는 읽은 내용을 나타내는 data:url 형식의 문자열이 있습니다
readAsTexx blob/file, [encoding] 은 텍스트로 읽혀지며, 결과의 문자열은 읽은 Content

방해 시 트리거됨

onerror오류가 발생하면 트리거됩니다onload읽기가 성공하면 트리거됩니다onloadend읽기가 완료되면 트리거됩니다. 성공 여부)onloadstart읽기가 시작될 때 트리거됨onprocess읽는 동안 트리거됨

BASE64:

我们用chrome打开一张图片,在resources里面显示的就是图片的base编码(实际上base编码比原图片稍大)

图片的base64编码也就是将一张图片编码成一个字符串,我们可以用这个字符串给img标签的src赋值,这样我们就可以看到这张图片。

如何编写:

在html中:

<span style="font-size: 14px;"><img src="data:image/gif;base64,R0lGODlhAwADAIABAL6+vv///yH5BAEAAAEALAAAAAADAAMAAAIDjA9WADs="></span>
로그인 후 복사

在css中:

<span style="font-size: 14px;">background-image:url(data:image/gif;base64,R0lGODlhBAABAIABAMLBwfLx8SH5BAEAAAEALAAAAAAEAAEAAAICRF4AOw==);</span>
로그인 후 복사

优缺点:

优点:1、减少了http请求;2、可以被gzip;3、没有跨域问题;4、无需考虑在更新图片时缓存问题。

缺点:1、ie8以下不支持;2、不论是写在css文件还是html文件中,增加了文件的大小;3、图片大了之后,程序员编码相当困难;

应用:

根据实际需求来选择base64显示图片,或者选择css sprite,或者直接使用png等

一般使用场景:很少被更新,实际尺寸很小,在系统中大量使用。

canvas压缩:

在移动应用场景中,用户上传的图片一般很大,会导致上传时间过长而失败,既浪费时间也浪费流量,更影响用户体验。我们可以使用canvas的drawImage方法的图形裁剪功能。

1、新建image对象,给其src复制base64值,在其监听onload事件;

2、在onload事件方法中新建canvas对象,获取上下文context;

3、设置裁剪比例,调用drawImage方法填充图片。

4、通过toDataUrl方法获取裁剪之后的base64值。

详细见下例。

Blob

在传输一些比较大的图片的base64是容易出现转发错误,这里我们可以将base64转换成blob字段写到form表单中提交到后台。一般blob和base64之间的相互转换通过fileReader 的readAsDataUrl和ArrayBuffer的charCodeAt方法。下面列举几个相互转换的方法。来自(http://jsperf.com/blob-base64-conversion)

<span style="font-size: 14px;"> var blobToBase64 = function(blob, cb) {<br>      var reader = new FileReader();<br>      reader.onload = function() {<br>        var dataUrl = reader.result;<br>        var base64 = dataUrl.split(',')[1];<br>        cb(base64);<br>      };<br>      reader.readAsDataURL(blob);<br>      };<br>  var base64ToBlob = function(base64, cb) {<br>      var binary = atob(base64);<br>      var len = binary.length;<br>      var buffer = new ArrayBuffer(len);<br>      var view = new Uint8Array(buffer);<br>      for (var i = 0; i < len; i++) {<br/>        view[i] = binary.charCodeAt(i);<br/>      }<br/>      cb(new Blob([view]));<br/>      };<br/>  var base64ToBlobSync = function(base64) {<br/>      var binary = atob(base64);<br/>      var len = binary.length;<br/>      var buffer = new ArrayBuffer(len);<br/>      var view = new Uint8Array(buffer);<br/>      for (var i = 0; i < len; i++) {<br/>        view[i] = binary.charCodeAt(i);<br/>      }<br/>      var blob = new Blob([view]);<br/>      return blob;<br/>      };<br/>  var blobToBase64_2 = function(blob, cb) {<br/>      var reader = new FileReader();<br/>      reader.onload = function() {<br/>        var buffer = reader.result;<br/>        var view = new Uint8Array(buffer);<br/>        var binary = String.fromCharCode.apply(window, view);<br/>        var base64 = btoa(binary);<br/>        cb(base64);<br/>      };<br/>      reader.readAsArrayBuffer(blob);<br/>      };</span>
로그인 후 복사

btoa 与 atob: ---在对base64转blob时就需要用atob对base64进行解码

btoa("javascript");     //"amF2YXNjcmlwdA=="
atob("amF2YXNjcmlwdA==") ;       //"javascript"
로그인 후 복사

注意:在需要转码中文时,需要用encodeURIComponent方法对中文处理,解码时用decodeURIComponent

btoa(encodeURIComponent("我喜欢 javascript"));    //"JUU2JTg4JTkxJUU1JTk2JTlDJUU2JUFDJUEyJTIwamF2YXNjcmlwdA=="
decodeURIComponent(atob("JUU2JTg4JTkxJUU1JTk2JTlDJUU2JUFDJUEyJTIwamF2YXNjcmlwdA=="));   //"我喜欢 javascript"
FormData:
로그인 후 복사

我们只需要使用new FormData()创建对象,然后append键值对,后用ajax向后台发生即可。

这里是往FormData对象添加blob字段。

注:使用Ajax将这个FormData对象提交到服务器上时,所发送的HTTP请求头中代表那个Blob对象所包含文件的文件名称的"Content-Disposition"请求头的值会是一个空字符串,这会引发某些服务器程序上的错误.从Gecko 7.0开始,这种情况下发送的文件名称改为"blob"这个字符串.

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0">
 <title>Document</title>
 <script src="http://apps.bdimg.com/libs/zepto/1.1.4/zepto.min.js"></script>   <!--引用baidu-->
</head>
<style>
.uploadPic{
 width: 92%;
   position: relative;
   margin: 0 auto;
   height: 2.8rem;
   line-height: 2.8rem;
   font-size: 1.3rem;
   border-radius: 4px;
   color: #fff;
   text-align: center;
   background-color: #72bcc5;
}
.uploadPic>input{
 position: absolute;
   display: block;
   width: 100%;
   height: 100%;
   right: 0;
   top: 0;
   opacity: 0;
}
.uploadPic>img{
 border:none;
}
</style>
<body>
 <p id="uploadPic" class="uploadPic">
 <span>拍摄</span>
 <input type="file" >  <!--这里可以添加multiple="true"属性,用来添加多张图片,然后对this.file[]数组操作-->
 <p style="line-height: 1rem;margin: 0.5rem 0;"><progress id="progress" value="0" max="100" style="width: 100%;"></progress></p> 
 <img src="" width="100%" style="height: 21rem;">
 </p>
</body>
<script>
 function upload(file, callBack) {
        var loading=0;
        var total=file.size;
        if(window.FileReader){
         $("#progress")[0].value=0;
         var fileReader = new FileReader();
         fileReader.onload = function() {
          console.log(fileReader.readyState);  //读取完成
             compressPic(this.result,callBack)
         };
         fileReader.onerror = function() {
          console.log(fileReader.error);
         };
         fileReader.onprogress = function (e){
          console.log(fileReader.readyState);  //读取中
          loading += e.loaded;
          $("#progress")[0].value=(loading / total) * 100; 
         }
         console.log(fileReader.readyState);  //未读取
         fileReader.readAsDataURL(file)
        }else{
         alert("您的浏览器不支持FileReader");
        }
    }
    function base64ConvertToBlob(picData, type, size) {
            type = type || "";
            size = size || 512;
            var decodeFileData = atob(picData);  //此处用atob解码,转码函数btoa。在使用方法时注意操作中文时,需对中文decodeURIComponent转换
            var dataArray = [];
            var len = decodeFileData.length;
            for (var i = 0; i < len; i += size) {
                var pieceData = decodeFileData.slice(i, i + size);   //这里做了一个512的分组
                var arr = new Array(pieceData.length);
                for (var j = 0; j < pieceData.length; j++) {
                    arr[j] = pieceData.charCodeAt(j)
                }
                var u8a = new Uint8Array(arr);
                dataArray.push(u8a)
            }
            return new Blob(dataArray, {type: type})
    }
    function compressPic(picData,callBack) {
        var img=new Image();
        img.onload = function(){
         var width = img.width;
         var height = img.height;
         var standard=800;  //以800为基准压缩
         if (width > standard || height > standard) {
             var rate = Math.max(width / standard, height / standard);
             width /= rate;
             height /= rate
         }
      var canvas = document.createElement("canvas");
         canvas.width = width;
         canvas.height = height;
         var context = canvas.getContext("2d");
         context.fillRect(0, 0, canvas.width, canvas.height);
         context.drawImage(img, 0, 0, width, height);
         var data = canvas.toDataURL("image/jpeg", 1);
         //var blobData=base64ConvertToBlob(data.replace(/^.*?,/, ""), "image/jpeg")  //-----需要去掉符号,不然使用atob方法报错
         //doAjax(new FormData().append('image',data));   //后续可以这样做,转换成Blob字段,组装FormData,发送至后台
         console.log("the after canvas compress size : " + data.length);
         callBack(data)
        };
        img.src=picData;
        console.log("the before canvas conpress size : "+picData.length);
    }
 $("#uploadPic input").change(function() {
 var file=this.files[0];
 upload(file, function(picData){
             $("#uploadPic img")[0].src = picData;    //预览
            }
        );
    });
</script>
</html></span>
로그인 후 복사

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

JS中特性与UA检测

Ajax的工作原理核心以及对象

위 내용은 H5를 사용하여 사진을 업로드하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿