TIL CORS

2023. 4. 21. 22:33TIL/2023.4월

2023.04.21 금

 

DRF를 사용하기 전 퓨어 django에서는 하나의 프로젝트에 templets 폴더에 html을 만들어 사용했지만 실제 프로젝트에는 프론트엔드와 백엔드를 분리하여 만든다고 합니다.

 

drf_week2_front라는 이름으로 폴더를 만들고 html파일과 js 파일을 만들어 줍니다. 이 폴더는 프로젝트와 무관한 새로운 폴더입니다.

drf_week2_front/index.html
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>프론트엔드</title>
    <script src="index.js"></script>  #js 파일을 사용하기 위해 사용
</head>

<body>
    <h1>프론트엔드</h1>
</body>

</html>
drf_week2_front/index.js
console.log("JS등장!") #페이지가 열리면 console창에 JS등장!을 찍어준다

라이브서버를 이용하여 연결이 잘 되었는지 확인해봅시다.

연결완료!

이제 js에서 drf 프로젝트의 articles 페이지를 불러오겠습니다.

window.onload = async function loadArticles() {
    const respons = await fetch('http://127.0.0.1:8000/articles/')

    respons_json = await respons.json()

    console.log(respons_json)
}

asyn, await 비동기식 방식에 관한 개념은 아래 링크의 글에서 너무 잘 설명해줍니다.(바로이해함)

https://kangworld.tistory.com/24

 

[C#] async await 기초 #1 : 동기 비동기 개념 이해하기

인트로 C# .NET FRAMEWORK 4.5부터 추가된 async awiat 키워드에 대해서 알아보려 한다. async awiat는 서버(ex 게임 서버 웹서버)를 구축할 때 사용되는 중요한 개념 중 하나다. 블로그에 정리하고 싶었는데

kangworld.tistory.com

fetch를 사용하여 도메인을 repons에 담아주고 json형태로 respons_json 형태로 담아 준 후 console에 출력시켜 보겠습니다.

오류가 발생합니다. CORS, Allow-Orgine가 키워드처럼 보입니다.

https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS

 

Cross-Origin Resource Sharing (CORS) - HTTP | MDN

Cross-Origin Resource Sharing (CORS) is an HTTP-header based mechanism that allows a server to indicate any origins (domain, scheme, or port) other than its own from which a browser should permit loading resources. CORS also relies on a mechanism by which

developer.mozilla.org

CORS가 교차 원본 리소스 공유의 약자네요.

글을 읽어보면 보안 등의 이유로 헤더에 따라 공지하지 않으면, 동일한 경로를 가지고 있지 않는 이상, 가져올 수 없다고 합니다.

사용을 위해 페이지를 가져올 django에 cors를 설정이 필요해보입니다.

django cors를 검색하여 봅시다.

https://pypi.org/project/django-cors-headers/

 

django-cors-headers

django-cors-headers is a Django application for handling the server headers required for Cross-Origin Resource Sharing (CORS).

pypi.org

 

따라가봅시다

pip을 해줍니다.

python -m pip install django-cors-headers

pip이 추가되었다면 할 것이 있죠?

pip freeze > requirements.txt

requirements.txt에 pip한 것을 추가해줍니다.

잘 들어왔습니다.

settings에 추가해줍니다.

INSTALLED_APPS = [
    ...,
    "corsheaders",
    ...,
]

마찬가지로 settings에 추가해줍니다.

단, commonMiddleware보다 위에 CorsMiddleware를 추가해주어야 합니다.

(두 개를 추가하는 것이 아니라, corsheaders...만 추가합니다.)

MIDDLEWARE = [
    ...,
    "corsheaders.middleware.CorsMiddleware",
    "django.middleware.common.CommonMiddleware",
    ...,
]

다음은 보안상 허용범위?를 정하는 것 같습니다.

  • CORS_ALLOWED_ORIGINS <-같은 origins만
  • CORS_ALLOWED_ORIGIN_REGEXES <-정규표현식이 같을 때
  • CORS_ALLOW_ALL_ORIGINS <-모든 orgins에서 가능

ALL_ORGINS를 사용하겠습니다.settings 가장 아래에 적어주겠습니다.

cors 설정이 끝났습니다, drf 서버가 꺼졌다면 다시 켜고 front 라이브서버 콘솔창으로 가보겠습니다.

잘 출력됩니다.

콘솔창에서 말고, html div를 만들어 웹페이지에 찍어주겠습니다.

html 파일에가서 id가 articles인 영역을 만들어줍니다.

<div id="articles">

</div>

js파일로 돌아와서 다음 코드를 사용합니다.

    const articles = document.getElementById("articles")

    respons_json.forEach(element => {
        console.log(element.title)
    });

html에서 만든 div에는 article의 title을 출력해 줄것입니다, 그것을 위해 articles라는 변수를 미리 만들어 줍니다.

 

respons_json을 for반복문을 사용하여 console창에 출력시키는데 이 때 title만 출력시킵니다.

키:값 형태의 dict 구조이기에  for반복문을 통해 title을 출력합니다.

forEach에 다음 코드를 추가합니다.

        const newArticle = document.createElement("div")
        newArticle.innerText = element.title
        articles.appendChild(newArticle)

newArticle은 div형태를 가진 인스턴스입니다.

innerText를 이용하여 newArticle에 요소의 title을 가져옵니다.

articles에 newArticle의 요소를 추가해줍니다.

js파일의 코드를 모아보면 이렇게 되어있네요

window.onload = async function loadArticles() {
    const respons = await fetch('http://127.0.0.1:8000/articles/')

    respons_json = await respons.json()

    console.log(respons_json)

    const articles = document.getElementById("articles")

    respons_json.forEach(element => {
        const newArticle = document.createElement("div")
        newArticle.innerText = element.title
        articles.appendChild(newArticle)
    });
}

이제 잘 작동되는지 확인하기 위해 사용했던 console은 지워줍니다.

 

저장 후 라이브서버를 통해 출력이 잘 되는지 확인합니다.

title만 잘 출력됩니다.

 

느낀점

왜 갑자기 js를 사용하여 프론트쪽을 구현하고 연동을 하는 과정을 강의에서 다뤘는지 먼저 생각했습니다.

CORS에 대하여 학습하기 위해 다뤘겠죠? 

 

처음 퓨어 django를 다뤘을 때 가장 들어가기 겁났던 파일은 settings.py입니다. 

뭐 하나 잘못 건드리면 고장날 거 같고 뭐가 뭔지 모르겠고 확실히 심화 과정에 들어오면서 본격적으로 settings.py를 다루어보니, 전혀 어려운 것이 아니었습니다, 공식문서나, 구글링으로 찾아보면 다 나오니까요ㅎㅎ

 

항상 돌이켜 생각해보면, 과거에 몰라서 힘들었던 부분은 정말 별 거 아니였습니다, python에서 상속 개념을 배웠을 때, django modle과 form에 대하여 너무 힘들어했을 때 정말 별 거 아니였습니다.

html로 치면 <> <-태그에 이걸 왜 사용해야하나요? css 영역에 끝에는 ; 이것을 왜 사용해야하죠? 이 정도 질문이였습니다.

그런데 왜 그렇게 힘들었을까요?

오늘만 해도 그렇습니다. 

asyn, await 비동기식 방식에 대한 개념이 없으니 js부분을 어떻게 설명해야하지 몰라 한참을 고민했습니다, 문서나 블로그를 찾아봐도 프라미스가 뭔지, 동기식처럼 사용한다는게 무슨 말인지 이게 왜 장점이고 편리한지 그렇게 한참 찾아보다가 링크로 남긴 저 블로그를 발견했고 고민한게 무색하게 금방 이해했습니다.

 

저는 이번 캠프에 참가하여 가장 크게 느낀게 포기하지 않으면 어떤 방식으로든 해결할 수 있다는 것을 알아가는 것 같습니다. 

만약 class 상속에서 포기했으면 저는 아직도 class 상속은 물론이고 django나 drf 어쩌면 python에 대해서도 모르는 상태로 살아갔을 것입니다, 포기하지 않고 계속 붙잡고 알려고 머리를 쥐어뜯었기에 알게 되었고 더 나아갈 수 있었던 것 같습니다.

 

아마 또 새로운 것을 배울 때 많이 힘들겠죠? 포기하고 싶기도 하고 그럴 때에는 요즘 점점 더 휑해지는 머리를 쥐어뜯으며 버티고 알아가야겠다 느꼈습니다.

 

'TIL > 2023.4월' 카테고리의 다른 글

TIL bin, int  (0) 2023.04.25
TIL onclick ()  (0) 2023.04.24
TIL CBV(클래스형 뷰), swagger  (0) 2023.04.20
TIL django 심화 DRF 프레임워크!  (0) 2023.04.19
TIL 장고 심화과정 mypy, Black, Django Ninja  (0) 2023.04.18