Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- R
- Kotlin
- JavaScript
- GIT
- react
- 공정능력
- Eclipse
- plugin
- 보조정렬
- Android
- SQL
- Java
- Sqoop
- vaadin
- window
- MSSQL
- mapreduce
- Express
- NPM
- xPlatform
- mybatis
- Spring
- SPC
- table
- hadoop
- IntelliJ
- es6
- tomcat
- SSL
- Python
Archives
- Today
- Total
DBILITY
pure javascript file upload 테스트 본문
반응형
기능을 테스트하며 기록을 남긴다.
back-end는 spring 4.3.9.RELEASE를 사용했다.
commons-fileupload를 사용하기 위해 pom에 dependency 추가
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.2.2</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
spring dispatcer설정(xml방식)에 CommonsMultipartResolver를 추가
<bean class="org.springframework.web.multipart.commons.CommonsMultipartResolver" id="multipartResolver">
<property name="defaultEncoding" value="UTF-8" />
<property name="maxUploadSize" value="262144000" />
<property name="maxUploadSizePerFile" value="262144000" />
<property name="maxInMemorySize" value="0" />
</bean>
테스트용 Controller를 추가하고 RequestMapping 처리
@RequestMapping(value = "/upload", method = RequestMethod.POST)
@ResponseBody
public String upload(@RequestParam("mediaFile") List<MultipartFile> files, @RequestParam("user") String user, HttpServletRequest request, HttpServletResponse response) throws Exception {
Gson gson = new Gson();
JsonObject obj = new JsonObject();
String uploadDir = request.getSession().getServletContext().getRealPath("/")+"resources";
logger.info("------------------> {} , {}", user, uploadDir);
if(files.size()>0){
try{
for (MultipartFile file : files){
if(!file.getOriginalFilename().isEmpty()){
logger.info("{}",file.getName());
logger.info("{}",file.getOriginalFilename());
byte[] bytes = file.getBytes();
File dir = new File(uploadDir);
if(!dir.exists()){
dir.mkdirs();
}
File uploadFile = new File(dir.getAbsolutePath() + File.separator + file.getOriginalFilename());
BufferedOutputStream uploadStream = new BufferedOutputStream(new FileOutputStream(uploadFile));
uploadStream.write(bytes);
uploadStream.close();
}
}
obj.addProperty("error",-1);
} catch (Exception e) {
obj.addProperty("error",1);
throw e;
}
}
return gson.toJson(obj);
}
html view
fetch는 아직 progress를 지원하지 않는다.XMLHttpRequest는 upload.onprogress로 지원.
이미지와 동영상파일을 선택했을때 base64로 연결하였다.
업로드할때 file로 변환 후 FormData에 추가
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Image & Video Base64 Upload Test</title>
<style>
button {
margin: 2px;
}
ul {
list-style-type: none;
}
progress {
margin-left: 10px;
}
</style>
</head>
<body>
<div>
<ul>
<li>
<button id="btnSelectImageFile">이미지선택</button>
<button id="btnUploadImage">이미지업로드</button>
</li>
<li>
<button id="btnSelectVideoFile">동영상선택</button>
<button id="btnUploadVideo">동영상업로드</button>
</li>
<li><label for="uploadProgress">Uploading progress:</label><progress id="uploadProgress" value="0" max="100"></progress></li>
</ul>
</div>
<script>
function log(){
for (let x of arguments) {
console.log(x);
}
}
function removeItem() {
["imageLayer","sImage","videoLayer","sVideo"].forEach((item,index)=>{
if(document.getElementById(item)) {
document.getElementById(item).remove();
}
});
document.getElementById("uploadProgress").setAttribute("value", "0");
}
function fnImageSelector() {
removeItem();
let divEle = document.createElement("div");
divEle.id = "imageLayer";
divEle.innerHTML = "<img id='img' />";
let fileEle = document.createElement("input");
fileEle.type = "file";
fileEle.id = "sImage";
fileEle.name = "sImage";
fileEle.style.display = "none";
fileEle.accept = "image/jpeg, image/png";
document.body.append(fileEle);
document.getElementById("sImage").addEventListener("change", function (e) {
let reader = new FileReader();
let file = null;
let fileName = null;
let fileType = null;
if (e.target.files.length > 0) {
document.body.append(divEle);
file = e.target.files[0];
fileName = file.name;
fileType = file.type;
reader.readAsDataURL(file);
reader.onload = function (e) {
let image = reader.result;
let imgObj = document.getElementById("img");
imgObj.setAttribute("src", image);
imgObj.setAttribute("data-fileName", fileName);
imgObj.setAttribute("data-fileType", fileType);
document.getElementById("sImage").remove();
};
} else {
document.getElementById("sImage").remove();
}
});
document.getElementById("sImage").click();
}
function fnUploadImageByXMLHttpRequest() {
let formData = new FormData();
let fileRes = document.getElementById("img").getAttribute("src");
let fileName = document.getElementById("img").getAttribute("data-filename");
let fileType = document.getElementById("img").getAttribute("data-filetype");
let file;
fetch(fileRes)
.then(result => result.blob())
.then(blob => {
file = new File([blob], fileName, {type: fileType});
file.type = fileType;
formData.append("mediaFile", file);
/*formData.append("mediaFile", file);
formData.append("mediaFile", file);
formData.append("mediaFile", file);
formData.append("mediaFile", file);*/
/* 동일이름으로 다른 파일을 추가하면 멀티업로드가 됨 */
/*formData.enctype='multipart/form-data';
formData.method='post';*/
return formData;
}).then(formData => {
formData.append("user", "hyperrookie@gmail.com");
let xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function (e) {
console.log(this.readyState + ":" + this.status + ":" + this.statusText);
/*1. UNSENT (숫자 0) : XMLHttpRequest 객체가 생성됨.
2. OPENED (숫자 1) : open() 메소드가 성공적으로 실행됨.
3. HEADERS_RECEIVED (숫자 2) : 모든 요청에 대한 응답이 도착함.
4. LOADING (숫자 3) : 요청한 데이터를 처리 중임.
5. DONE (숫자 4) : 요청한 데이터의 처리가 완료되어 응답할 준비가 완료됨.
- 200 : 서버에 문서가 존재함.
- 404 : 서버에 문서가 존재하지 않음.
*/
if (this.readyState == XMLHttpRequest.DONE) {
if (this.status == 200) {
log(this.response, this.responseText);
} else {
log(this.response, this.statusText);
}
}
};
xhttp.upload.onprogress = function(e){
if(e.lengthComputable) {
log(e.total, e.loaded);
document.getElementById("uploadProgress").setAttribute("value", String(Number(e.loaded / e.total) * 100));
} else {
log(e.loaded);
document.getElementById("uploadProgress").setAttribute("value", "0");
}
};
xhttp.onerror = function (e) {
log(e);
};
xhttp.open("POST", "/upload", true);
xhttp.send(formData);
}).catch(error => {
log(error);
});
}
function fnUploadImageByFetch() {
let formData = new FormData();
let fileRes = document.getElementById("img").getAttribute("src");
let fileName = document.getElementById("img").getAttribute("data-filename");
let fileType = document.getElementById("img").getAttribute("data-filetype");
let file;
fetch(fileRes)
.then(result => result.blob())
.then(blob => {
file = new File([blob], fileName, {type: fileType});
file.type = fileType;
formData.append("mediaFile", file);
return formData;
}).then(formData => {
formData.append("user", "hyperrookie@gmail.com");
fetch("/upload", {
method: "POST",
headers: {},
body: formData
}).then(response => {
log(response.status);
}).catch(error => {
log(error);
});
}).catch(error => {
log(error);
});
}
function fnVideoSelector() {
removeItem();
let divEle = document.createElement("div");
divEle.id = "videoLayer";
divEle.innerHTML = "<video id='movie' />";
let fileEle = document.createElement("input");
fileEle.type = "file";
fileEle.id = "sVideo";
fileEle.name = "sVideo";
fileEle.style.display = "none";
fileEle.accept = "video/mp4, video/webm";
document.body.append(fileEle);
document.getElementById("sVideo").addEventListener("change", function(e){
let reader = new FileReader();
let file = null;
let fileName = null;
let fileType = null;
if( e.target.files.length > 0) {
file = e.target.files[0];
fileName = file.name;
fileType = file.type;
if(Number(file.size/1024/1024) > 220){
window.alert("용량초과");
this.remove();
return;
};
document.body.append(divEle);
reader.readAsDataURL(file);
reader.onload = function(e) {
let video = reader.result+"#t=10";
let videoObj = document.getElementById("movie");
videoObj.childNodes.forEach((node,index)=>{
node.remove();
});
//videoObj.innerHTML = "<source src='"+video+"' type='"+fileType+"'/>";
videoObj.setAttribute("src", video);
videoObj.setAttribute("data-fileName", fileName);
videoObj.setAttribute("data-fileType", fileType);
videoObj.setAttribute("autoplay", false);
videoObj.setAttribute("loop", true);
videoObj.setAttribute("controls", true);
videoObj.play();
document.getElementById("sVideo").remove();
};
} else {
document.getElementById("sVideo").remove();
}
});
document.getElementById("sVideo").click();
}
function fnUploadVideoByXMLHttpRequest() {
let formData = new FormData();
let fileRes = document.getElementById("movie").getAttribute("src");
let fileName = document.getElementById("movie").getAttribute("data-filename");
let fileType = document.getElementById("movie").getAttribute("data-filetype");
let file;
fetch(fileRes)
.then(result => result.blob())
.then(blob => {
file = new File([blob], fileName, {type: fileType});
file.type = fileType;
formData.append("mediaFile", file);
return formData;
}).then(formData => {
formData.append("user", "hyperrookie@gmail.com");
let xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function (e) {
console.log(this.readyState + ":" + this.status + ":" + this.statusText);
/*1. UNSENT (숫자 0) : XMLHttpRequest 객체가 생성됨.
2. OPENED (숫자 1) : open() 메소드가 성공적으로 실행됨.
3. HEADERS_RECEIVED (숫자 2) : 모든 요청에 대한 응답이 도착함.
4. LOADING (숫자 3) : 요청한 데이터를 처리 중임.
5. DONE (숫자 4) : 요청한 데이터의 처리가 완료되어 응답할 준비가 완료됨.
- 200 : 서버에 문서가 존재함.
- 404 : 서버에 문서가 존재하지 않음.
*/
if (this.readyState == XMLHttpRequest.DONE) {
if (this.status == 200) {
log(this.response, this.responseText);
} else {
log(this.response, this.statusText);
}
}
};
xhttp.upload.onprogress = function(e){
if(e.lengthComputable) {
log(e.total, e.loaded);
document.getElementById("uploadProgress").setAttribute("value", String(Number(e.loaded / e.total) * 100));
} else {
log(e.loaded);
document.getElementById("uploadProgress").setAttribute("value", "0");
}
};
xhttp.onerror = function (e) {
log(e);
};
xhttp.open("POST", "/upload", true);
xhttp.send(formData);
}).catch(error => {
log(error);
});
}
function fnUploadVideoByFetch() {
let formData = new FormData();
let fileRes = document.getElementById("movie").getAttribute("src");
let fileName = document.getElementById("movie").getAttribute("data-filename");
let fileType = document.getElementById("movie").getAttribute("data-filetype");
let file;
fetch(fileRes)
.then(result => result.blob())
.then(blob => {
file = new File([blob], fileName, {type: fileType});
file.type = fileType;
formData.append("mediaFile", file);
return formData;
}).then(formData => {
formData.append("user", "hyperrookie@gmail.com");
fetch("/upload", {
method: "POST",
headers: {},
body: formData
}).then(response => {
log(response.status);
}).catch(error => {
log(error);
});
}).catch(error => {
log(error);
});
}
window.addEventListener("load", e => {
let btnList = document.querySelectorAll("button");
btnList.forEach((node, index) => {
node.addEventListener("click",e => {
e.preventDefault();
let btnId = e.currentTarget.id;
if (btnId == "btnSelectImageFile") {
fnImageSelector();
} else if (btnId == "btnUploadImage") {
fnUploadImageByFetch();
//fnUploadImageByXMLHttpRequest();
} else if (btnId == "btnSelectVideoFile") {
fnVideoSelector();
} else if (btnId == "btnUploadVideo") {
fnUploadVideoByFetch();
//fnUploadVideoByXMLHttpRequest();
}
});
});
});
</script>
</body>
</html>
반응형
'front-end & ui > javascript' 카테고리의 다른 글
div move + rotate + resize test (0) | 2021.05.20 |
---|---|
div rotate test (0) | 2021.05.18 |
div drag test (0) | 2021.05.14 |
EventSource + Spring Server Sent Event (0) | 2021.05.12 |
ajax download (0) | 2019.06.03 |
Comments