본문 바로가기
블로그 이미지

방문해 주셔서 감사합니다! 항상 행복하세요!

  
   - 문의사항은 메일 또는 댓글로 언제든 연락주세요.
   - "해줘","답 내놔" 같은 질문은 답변드리지 않습니다.
   - 메일주소 : lts06069@naver.com


Javascript/[중요] Javascript

Javascript 파일을 binary문자열로 전송한 뒤 변환하여 서버에 저장하기

야근없는 행복한 삶을 위해 ~
by 마샤와 곰 2020. 9. 18.

브라우저에서 파일을 binary데이터로 변환하여 문자로 변환한 뒤에 json형식으로 전송한 뒤에 서버에서 파일로 다시 변환하는 특이한(?) 경우가 있었습니다.

브라우저에서 일반적인 json형식의 크기와 사이즈는 검색하면 바로 확인하여 볼 수 있습니다.

기본크기와 캐릭터숫자가 잘 나와 있습니다.

 

json형식으로 파일을 보내려다 보니 용량제한에 좀 민감하여 신경을 썼던 것 같습니다.

Jquery를 활용하여 먼저 파일을 전송하는 기능을 만들어 주었습니다.

먼저 아래는 단순한 html 파일 형식입니다.

<!DOCTYPE html>
<html>
  <head>
  	<meta http-equiv="X-Frame-Options" content="deny" />
	<meta charset="UTF-8">
	<meta name="description" content="">
	<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
	<script src="https://code.jquery.com/jquery-2.2.1.min.js"></script>
    <title>테스터</title>
  </head>
  <body>
    <input type='file' id='file'/>
    <input type='button' class='btn btn-blue addSettingInfo' value='보내기'onclick='sendTest()'/>
  </body>
</html>

 

다음으로 실제 전송하는 sendTest함수 입니다.

input type file 같은 경우에는 보안상 다양한 정보가 존재하지 않습니다.

그리하여 Javascript에서 제공하는 FileReader를 활용하였습니다.

function sendTest(){
    var fff = $('#file')[0].files;  //파일테그 정보값
    var reader = new FileReader();
	
    reader.onload = function(e) {
        var arrayBuffer = e.target.result;
        arrayBufferToBase64(arrayBuffer).then( (byte8) => {
            var parameter = {
                arg:'일반문자',
                name : fff[0].name,
                data : byte8
            };
            $.ajax({
                url: '/testFileUploader.do',
                data:parameter,
                type: 'post',
                success: function (res) {
                    console.log(res);
                },
                error : function(err){
                    console.log('error');
                    console.log(err);
                }
            });	
        }) .catch( (err)=>{
            console.log(err);
        });
    }
    reader.readAsArrayBuffer(fff[0]);  //시작~
}

function arrayBufferToBase64(buffer) {
    return new Promise( (succ,fail)=>{
        try {
            var binary = '';
            const bytes = new Uint8Array(buffer);
            const len = bytes.byteLength;
            for (let i = 0; i < len; i++) {
                binary += String.fromCharCode(bytes[i]);
            }
            succ( window.btoa(binary) );	    	
        } catch(e){
            console.log('to big....');
            fail(e);
        }	
    });
}

 

FileReader를 활용하여 파일정보를 가장 먼저 바이트 배열로 값을 읽었습니다.

그리고나서 arrayBufferToBase64함수를 통해서 64진법(base64)의 문자열로 변경하였습니다.

Promise를 통해서 순서를 보장하였으며, 완료된 문자는 ajax를 통해서 서버로 전송하였습니다.

 

받는 서버는 간단하게 java로 구현하였습니다.

@RequestMapping(value = "/testFileUploader.do")
@ResponseBody
public String testFileUploader(@RequestParam HashMap<Object, Object> param){
    if(param.get("data") == null){
        System.out.println("파일문자열이 비어있습니다!");
    } else {
        binaryToFile(param.get("data").toString(), "저장경로", param.get("name").toString());	
    }
    return "SUCC";
}
	
	
public static File binaryToFile(String binaryFile, String filePath, String fileName) {
    if ((binaryFile == null || "".equals(binaryFile)) || (filePath == null || "".equals(filePath))
        || (fileName == null || "".equals(fileName))) { return null; }
	 
    FileOutputStream fos = null;
 
    File fileDir = new File(filePath);
    if (!fileDir.exists()) {
        fileDir.mkdirs();
    }
	 
    File destFile = new File(filePath + fileName); 
    
    byte[] buff = binaryFile.getBytes();
    String toStr = new String(buff);
    byte[] b64dec = Base64.decodeBase64(toStr);
	 
    try {
        fos = new FileOutputStream(destFile);
        fos.write(b64dec);
        fos.close();
    } catch (IOException e) {
        
    } 
    return destFile;
}

 

브라우저에서 Base64형태로 보낸 데이터를 디코드 하여 파일로 변환하였습니다.

테스트를 해 보면 대략적으로 약 1.5메가바이트 파일까지 문자열로 변환하여 파일전송은 가능합니다.

그런데 용량이 조금 커버리면 해당 전송방법으로는 파일을 전송할 수 없습니다.ㅠ

4메가가 좀 넘는 파일을 바이너리로 변환한 뒤에 json방식으로 보내자 오류가 발생 합니다.

 

물론 이러한 경우처럼 파일을 전송하는 경우는 많지 않을 것 같습니다.

 

반응형
* 위 에니메이션은 Html의 캔버스(canvas)기반으로 동작하는 기능 입니다. Html 캔버스 튜토리얼 도 한번 살펴보세요~ :)
* 직접 만든 Html 캔버스 애니메이션 도 한번 살펴보세요~ :)

댓글