RestController / 8
let valid = e.dataTransfer &&
e.dataTransfer.types &&
e.dataTransfer.types.indexOf("Files") >= 0; //드래그 한 내용이 파일이냐?!
imgDropZone.ondrop = function (e) {
e.preventDefault();
//파일이 몇갠지 알아보기
console.log(e.dataTransfer.files.length);
console.log("drop")
};
- 제약조건 걸기
.invalid-for-over {
background-color: peachpuff;
}
.invalid-for-drop{
background-color: orangered;
}
.invalid-for-drop::after{
display: inline-block;
content: '파일은 한개만 드롭할수 있슴돠';
}
- '파일은 한개만 놓을수 있습니다' 경고문 보여줬다가 사라지게 하는 로직
imgDropZone.ondrop = function (e) {
e.preventDefault();
//파일이 몇갠지 알아보기
if(e.dataTransfer.files.length>1){
imgDropZone.classList.add("invalid-for-drop");
setTimeout(()=>{
imgDropZone.classList.remove("invalid-for-drop");
imgDropZone.classList.remove("invalid-for-over");
},1000);
}
console.log("drop")
};
- 100메가보다 큰 파일 못올리게 하는 로직
.invalid-for-drop-size::after {
display: inline-block;
position: relative;
top: -100px;
content: '100메가 이상의 파일은 업로드 할수 없습니다.';
}
if (e.dataTransfer.files[0].size > 100*1024*1024) {
imgDropZone.classList.add("invalid-for-drop");
setTimeout(() => {
imgDropZone.classList.remove("invalid-for-drop");
imgDropZone.classList.remove("invalid-for-over");
}, 1000);
return;
}
let img = document.createElement("img");
img.src = "img/aa.jpg";
img.position = "absolute";
img.left = 0;
img.top=0;
e.target.appendChils(img);
- 로컬 파일을 읽어들일수 있는 코드
let imgReader = new FileReader()
let imgFile = e.dataTransfer.files[0];
let imgReader = new FileReader();
imgReader.onload = function(e){
let img = document.createElement("img");
img.src = "img/aa.jpg";
img.position = "absolute";
img.left = 0;
img.top = 0;
e.target.appendChils(img);
}
//파일을 읽어오는것만 할테니까
//니네가 띄워
imgReader.readAsDataURL(imgFile);
console.log("drop")
- homecontroller에서 home은 루트 그 자체를 의미한다
- 구조/하위구조/대상/id/속성/
- 파일 가져오는..내장 메서드?? 리턴값도 저거 고정임
@PostMapping
public String add(MultipartFile file) {
return file.getOriginalFilename();
}
- 파일 업로드를 위한 기본 준비
<form action="/api/files" method="post" enctype="multipart/form-data">
<input type="file" name="aa">
<input type="submit" value="등록">
</form>
//-------------------------------------------------------------------------
@RestController("apiFileController")
@RequestMapping("api/files")
public class FileController {
@PostMapping
public String add(MultipartFile aa) {
System.out.println(aa.getOriginalFilename());
return aa.getOriginalFilename();
}
}
- 입력값의 유효성 검사 : required
- 멀티파트는 문자열외에 다양한 것들을 심을수 있다(?)
btnOk.onclick = function(e){
e.preventDefault();
let formData = new FormData();
//form태그 없이도 form태그를 대신할수 있는 도구를 만든것.
formData.append("bb","hello~");
if(file) //트루시일 경우만 실행되게
formData.append("aa",file);
//해서~ 키,값으로 보낸다
let request = new XMLHttpRequest();
request.open("POST","/api/files");
request.send(formData);
console.log("aa");
}
- 가벼운 함수 정의하기
async () =>{
let response = await fetch("/api/files",{
method:'POST',
body:formData
});
};
- 비동기가 싫으면 await를 붙여라
(async () =>{
let response = await fetch("/api/files",{
method:'POST',
body:formData
});
let json = await response.json();
console.log(json);
})();
// })>감싸고 ()바로 호출!
- 프로미스는 콜백함수는 내가 실행해줄게! 너는 업무데이터만 넘겨~ 하는애임. 그리고 동기적으로 실행될수 있게함
근데 async를 쓰면 뒤에서 받았던 then절을 앞으로 받을수 있음
- await는 ui를 먹는곳에선 절대 쓸수없음
- 동기라는것은 어떤것이 실행될때 다른 어떤것은 절대 실행되지 못하게 하는것 = 기다리게 하는것
- 걍 프로미스는 중첩을 줄이려고 등장한것임
- 근데 동기형은 ui단에서는 사용하면 안됨..사용자들이 기다려야되니까
- 메인쓰레드에서 동기형을 써서 멈추게 하면 안된다. 화면 갱신도 안되고 사용자 이벤트도 못받고 뭣도 못함...그래서 그걸 백그라운드로 뺀다는듯...