javascript fetch api
fetch() 함수는 첫번째 인자로 URL, 두번째 인자로 옵션 객체를 받고, Promise 타입의 객체를 반환합니다. 반환된 객체는, API 호출이 성공했을 경우에는 응답(response) 객체를 resolve하고, 실패했을 경우에는 예외(error) 객체를 reject합니다.
fetch(url, options)
.then((response) => console.log("response:", response))
.catch((error) => console.log("error:", error));
대부분의 REST API들은 JSON 형태의 데이터를 응답하기 때문에, 응답(response) 객체는 json() 메서드를 제공합니다.
fetch("https://jsonplaceholder.typicode.com/posts/1")
.then((response) => response.json())
.then((data) => console.log(data));
POST,PUT,DELETE 요청 시 headers 옵션을 통해 JSON 포멧을 사용한다고 알려줘야 하며, 요청 전문을 JSON 포멧으로 직렬화화여 가장 중요한 body 옵션에 설정해줍니다.
fetch("https://jsonplaceholder.typicode.com/posts", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
title: "Test",
body: "I am testing!",
userId: 1,
}),
}).then((response) => console.log(response));
사용성 개선을 위해 함수로 빼서 사용 할 수 도 있다. 프로젝트의 상황에 맞게 다음과 같이 async/await 키워드를 이용하여 HTTP 방식별로 비동기 함수를 작성하고 모듈화하여 사용하곤 합니다.
async function post(host, path, body, headers = {}) {
const url = `https://${host}/${path}`;
const options = {
method: "POST",
headers: {
"Content-Type": "application/json",
...headers,
},
body: JSON.stringify(body),
};
const res = await fetch(url, options);
const data = await res.json();
if (res.ok) {
return data;
} else {
throw Error(data);
}
}
post("jsonplaceholder.typicode.com", "posts", {
title: "Test",
body: "I am testing!",
userId: 1,
})
.then((data) => console.log(data))
.catch((error) => console.log(error));
[출처] https://www.daleseo.com/js-window-fetch/
프로젝트에서 사용한 코드
- 마이갤러리 페이지를 불러오는 fetch api (GET 예시)
async function getMyGalleryList() {
const response = await fetch(`${backend_base_url}/mygallery/`, {
headers: {
Accept: "application/json",
'content-type': "application/json",
"Authorization": "Bearer " + localStorage.getItem("access")
},
method: 'GET',
// body: JSON.stringify(Data)
})
response_json = await response.json()
if (response.status == 200) {
- 마이갤러리 상품 수정 fetch api (PUT 예시)
// modal - 상품 수정
async function updateProduct(product_id) {
const description = document.getElementById("description_" + product_id).value
const price = document.getElementById("price_" + product_id).value
const is_selling = document.getElementById("is_selling_" + product_id).value
const response = await fetch(`${backend_base_url}/mygallery/${product_id}`, {
headers: {
Accept: "application/json",
'content-type': "application/json",
"Authorization": "Bearer " + localStorage.getItem("access")
},
method: 'PUT',
body: JSON.stringify(Data)
})
alert("수정이 완료되었습니다.")
window.location.reload()
}
- 마이갤러리 상품 삭제 fetch api (DELETE 예시)
// modal - 상품 삭제
async function deleteProduct(product_id) {
if (confirm("정말 상품을 삭제하시겠습니까?")) {
const response = await fetch(`${backend_base_url}/mygallery/${product_id}`, {
headers: {
Accept: "application/json",
'content-type': "application/json",
"Authorization": "Bearer " + localStorage.getItem("access")
},
method: 'DELETE',
// body: JSON.stringify(Data)
})
response_json = await response.json()
alert(response_json["result"])
window.location.reload()
}
}
제작한 유화 S3 업로드 및 DB 등록 fetch api (POST 예시)
// 이미지 업로드 (S3)
async function product_upload() {
// 이미지와 함께 저장하기 위해서 FormData 클래스 사용
const formdata = new FormData();
formdata.append("img_path", img_path)
// 라디오 버튼 중 선택된 항목의 value 가져오기
categoryNodeList = document.getElementsByName('painting-category');
shapeNodeList = document.getElementsByName('painting-shape');
categoryNodeList.forEach((node) => {
if (node.checked) {
formdata.append("category", node.value)
console.log(node.value)
}
})
shapeNodeList.forEach((node) => {
if (node.checked) {
formdata.append("img_shape", node.value)
console.log(node.value)
}
})
formdata.append("title", document.querySelector("#title").value)
formdata.append("description", document.querySelector("#description").value)
formdata.append("price", document.querySelector("#price").value)
payload = localStorage.getItem("payload")
payload = JSON.parse(payload)
formdata.append("created_user", payload["user_id"])
formdata.append("owner_user", payload["user_id"])
const response = await fetch(`${backend_base_url}/ai/`, {
headers: {
// Accept: "application/json",
// 'content-type': "application/json",
"Authorization": "Bearer " + localStorage.getItem("access"),
},
method: 'POST',
body: formdata,
})
response_json = await response.json()
console.log(response_json)
alert('유화 등록 완료~!')
window.location.replace(`${frontend_base_url}/templates/art/mygallery.html`);
}
file이 포함된 데이터는 Formdata 객체에 담아서 보내줘야한다. headers 에도 형식을 자동으로 인식할 수 있도록 바꿔줘야한다. 여러개의 file 포함될 경우에는 content-type을 'Content-Type': 'multipart/form-data' 로 명시해줘야한다
javascript 이미지 미리보기 - file태그 onchange 시 호출 되는 함수
// 이미지 미리보기
function base_image_preview(input) {
const base_div = document.querySelector("#base_img_preview")
base_div.innerHTML = `<img src="" id="result_base_file" class="base-img">`
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
document.getElementById('result_base_file').src = e.target.result;
};
reader.readAsDataURL(input.files[0]);
} else {
document.getElementById('result_base_file').src = "";
}
}
javascript input radio 타입의 선택된 항목의 value 가져오기
// input radio 타입 중 선택된 항목의 value 가져오기
categoryNodeList = document.getElementsByName('painting-category');
shapeNodeList = document.getElementsByName('painting-shape');
categoryNodeList.forEach((node) => {
if (node.checked) {
formdata.append("category", node.value)
console.log(node.value)
}
})
shapeNodeList.forEach((node) => {
if (node.checked) {
formdata.append("img_shape", node.value)
console.log(node.value)
}
})
javascript 날짜 포맷팅, 숫자 , 로 끊어서 보여주는 함수 to.LocaleString()
// 로그 기록들 출력
for (var i = 0; i < mygallery.log.length; i++) {
// 날짜 포맷팅
var updated_date = new Date(mygallery.log[i]['updated_date']);
var log_updated_dateString = updated_date.getFullYear() + '-' + (updated_date.getMonth() + 1) + '-' + updated_date.getDate();
const history = document.getElementById("history_box_" + mygallery.id)
// append를 이용하기 위해서 div 생성
const history_item = document.createElement('p')
if(i == 0){
history_item.innerHTML =
`${log_updated_dateString} 에 ${mygallery.log[i].old_owner} 님이 ${mygallery.log[i].old_price.toLocaleString()} 원에 생성`
} else {
history_item.innerHTML =
`${log_updated_dateString} 에 ${mygallery.log[i].old_owner} 님이 ${mygallery.log[i].old_price.toLocaleString()} 원에 구매`
}
history.prepend(history_item)
}
javascript arrow function
var elements = [
'Hydrogen',
'Helium',
'Lithium',
'Beryllium'
];
// 이 문장은 배열을 반환함: [8, 6, 7, 9]
elements.map(function(element) {
return element.length;
});
// 위의 일반적인 함수 표현은 아래 화살표 함수로 쓸 수 있다.
elements.map((element) => {
return element.length;
}); // [8, 6, 7, 9]
// 파라미터가 하나만 있을 때는 주변 괄호를 생략할 수 있다.
elements.map(element => {
return element.length;
}); // [8, 6, 7, 9]
// 화살표 함수의 유일한 문장이 'return'일 때 'return'과
// 중괄호({})를 생략할 수 있다.
elements.map(element => element.length); // [8, 6, 7, 9]
[출처] https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Functions/Arrow_functions
javascript forEach 문
// for문을 이용한 배열 조회
for(let i = 0; i < 배열명.length; i++){
console.log(i);
}
// forEach문을 이용한 배열 조회 - index 번호랑, array는 배열객체
배열명.forEach(function(item, index, array){
console.log(item, index, array);
});
// arrow function 까지 이용한 배열 조회
배열명.forEach(item, index, array => {
console.log(item, index, array);
});
// 화살표 함수의 유일한 문장이 'return'일 때 'return'과
// 중괄호({})를 생략할 수 있다.
배열명.forEach(i => console.log(i));
// 이차원 배열 조회
배열명.forEach(row => {
console.log(row) // (3) [td, td, td]
row.forEach(td => {
console.log(td) // <td></td>
}
}
[출처] https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach
javacript modal
// detail modal on
function detail_modalOn(product_id) {
const detail_modal = document.getElementById("detail_modal_" + product_id)
detail_modal.style.display = "flex"
detail_modal.style.top = window.pageYOffset + 'px';
document.querySelector('body').style.overflow = 'hidden'
}
// detail modal off
function detail_modalOff(product_id) {
const detail_modal = document.getElementById("detail_modal_" + product_id)
detail_modal.style.display = "none"
detail_modal.style.top = window.pageYOffset + 'px';
document.querySelector('body').style.overflow = 'scroll'
}
// 모달창 바깥 클릭 시 모달창 닫히게
window.addEventListener("click", e => {
const evTarget = e.target
if (evTarget.classList.contains("modal-overlay")) {
detail_modal.style.display = "none";
}
})
'회고록(TIL&WIL)' 카테고리의 다른 글
TIL 2022.07.11 DRF TestCode (0) | 2022.07.11 |
---|---|
TIL 2022.07.11 Docker (0) | 2022.07.11 |
WIL 2022.07.06 SMOPS 유화제작 팀프로젝트 - S.A & KPT (0) | 2022.07.06 |
WIL 2022.07.01 CORS, rest_framework_simplejwt, E2E 회원가입/로그인 (0) | 2022.07.02 |
TIL 2022.06.25 DRF/ 아침 숙제 풀이 (0) | 2022.06.25 |