브라우저에서 파일을 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메가바이트 파일까지 문자열로 변환하여 파일전송은 가능합니다.
그런데 용량이 조금 커버리면 해당 전송방법으로는 파일을 전송할 수 없습니다.ㅠ
물론 이러한 경우처럼 파일을 전송하는 경우는 많지 않을 것 같습니다.
반응형
'Javascript > [중요] Javascript' 카테고리의 다른 글
프론트와 백그라운드 개발 환경 분리, 파셀(Parcel) (0) | 2021.01.05 |
---|---|
Jquery auto table rowSpan(Jquery 자동 테이블 병합, 자동 table rowspan) (1) | 2020.11.18 |
Javascript firebase fire-store 연동, 자바스크립트 파이어베이스 fire-store 연동 (2) | 2020.05.18 |
파셀(parcel)을 활용하여 함수, 변수를 export 하기 (parcel export function) (4) | 2020.02.28 |
Javascript를 활용하여 데이터(배열)를 테이블로, 테이블 태그를 엑셀로(Javascript make excel file) (2) | 2020.02.27 |
* 위 에니메이션은 Html의 캔버스(canvas)기반으로 동작하는 기능 입니다. Html 캔버스 튜토리얼 도 한번 살펴보세요~ :)
* 직접 만든 Html 캔버스 애니메이션 도 한번 살펴보세요~ :)
댓글