본문 바로가기
개발/Django_python 웹 프레임워크

Network] HTTP 패킷 / Get, Post(feat. Django)

by 자유로운 코끼리 2020. 7. 15.
728x90

HTTP

- Hyper-Text Transfer Protocol(HTTP)www 상에서 문서를 주고받는 프로토콜입니다.

TCP, UDP를 사용하며, 80 포트를 사용합니다.

 

여기서 말하는 Hyper-Text란 참조를 통해서 한 문서에서 관련된 다른 문서들로 넘나들며

원하는 정보를 얻을 수 있게 해주는 텍스트를 말합니다.

 

프로토콜은 통신규약으로, 쉽게 생각하면 우리가 도로에서 빨간불이면 멈추는 등의 교통법이 있는 것처럼

인터넷에서 통신을 할 때도 이런 규칙이 존재합니다.

인터넷에서 데이터를 주고받을 수 있는 통신 규약(규칙)인 겁니다.

 

웹 상에서 통신을 주고 받을 수 있는 주체는 서버클라이언트입니다.

즉, 서버와 클라이언트 간 통신을 주고 받을 때 쓴 규칙을 HTTP라 하죠.

일반적으로 클라이언트웹브라우저를 말하며 django restful API로 안드로이드 등

앱과 연결 시킬 경우에는 클라이언트가 바뀔 수도 있겠죠.

 

자, 사용자가 URL을 브라우저 주소창에 작성하고 엔터를 누르면 웹페이지가 나옵니다.

이때 특정 웹페이지를 사용자 웹브라우저에게 보여주기 위해서는 내부적인 처리들이 있습니다.

그 내부적인 처리에서, 클라이언트가 서버에게 웹페이지를 보여달라고 말하는 것요청 이라 부르고,

서버가 클라이언트에게 요청받은 것에 대한 대답으로,

웹페이지 내용을 표현하기 위해 html문서로 주는것을 응답 이라 부른다. 

 

HTTP에사용하는 여러 가지 메소드는 있는데

HTTP/1.0 스 펙에 기재되어 있는 요청 방법에는 GET, HEAD, POST 방식이 있으며

1.1 스펙에서 추가 된 PUT, DELETE, TRACE 방식이 있습니다

 

HTTP 패킷

클라이언트가 서버로 요청 할 때, 보내는 데이터를 HTTP 패킷이라 표현합니다. 

HTTP 프로토콜을 이용하면서, 인터넷을 통해 데이터를 보내므로(이를 패킷이라 함) HTTP 패킷이라 합니다.

HTTP 패킷의 구조는 크게 헤더바디로 나뉘어집니다.

 

헤더에는 HTTP 메서드 방식중 무엇을 썻는지, 클라이언트의 정보, 브라우저 정보, 접속할 URL 등등 과 같은

클라이언트 정보를 담습니다. 

  

바디는 보통 비어있다가, 특정 데이터를 담아서 서버에게 요청을 보낼 수 있습니다.

 

요청과 응답은 각각 헤더와 본문으로 나뉘어집니다.

  • 요청헤더 (Request Header) : 요청하는 페이지의 주소와 현재 컴퓨터의 정보가 전송되는 부분입니다.
  • 요청바디 (Request Body) : POST 요청시 전송되는 데이터가 들어가는 부분입니다. GET 요청 때는 빈칸 입니다.
  • 응답헤더 (Response Header) : 응답 페이지의 상태와 서버에 관한 정보가 전송되는 부분입니다.
  • 응답바디 (Response Body) : 페이지의 HTML 소스가 전송되는 부분입니다.

     

HTTP의 메소드

GET(가져오다) URL에 표시된 리소스를 가져오기
POST(게시하다) Body에 정보를 담아 서버에 입력
PUT(집어넣다) URL에 표시된 리소스와 바꿔 치기
PATCH(고치다) PUT과 다르게 일부만 수정
DELETE(지우다) URL에 표시된 특정 리소소를 삭제

 

이제 우리는 http 메소드 중 get과 post 방식에 대해서 더 알아볼텐데,

그 이유는 쟝고에서 제공하는 http가 이 두가지이기 때문입니다.

 

Get 방식

서버로부터 정보를 조회하기 위해 설계된 메소드입니다. 

 

GET은 요청을 전송할 때 필요한 데이터를 Body에 담지 않고, 쿼리스트링을 통해 전송합니다.

클라이언트로가 입력한 쿼리의 이름과 값이 결합되어 스트링 형태로 서버에 전달되는거죠.

쿼리스트링은

URL의 끝에 ?와 함께 이름과 값으로 쌍을 이루는 요청 파라미터를 뜻합니다.

즉, get에서는 주소창을 통해 데이터를 보내주는 겁니다. 

 

이때 만약, 요청 파라미터가 여러 개이면 &로 연결합니다.

또한 쿼리스트링을 사용하게 되면 URL에 조회 조건을 표시하기 때문에,

특정 페이지를 링크하거나 북마크할 수 있습니다.

 

그리고 GET은 불필요한 요청을 제한하기 위해 요청이 캐시될 수 있습니다.

 

*캐시?

더보기

캐시

CDN같은 공유 캐시가 아닌 개인 캐시를 말합니다. 브라우저에 응답으로 온 HTML이나 JSON같은 데이터가 저장되어 나중에 서버에 요청을 보내지 않고도 브라우저에 저장된 응답을 사용할 수 있습니다.

보통 캐싱은 GET 요청에만 이루어집니다. GET이 조회하기 위해 만들어진 아이이다 보니, 가져온 데이터를 저장해두고 두고두고 쓰는 것이죠. 일반적으로 200(가져오기 성공), 301(다른 주소로 이동 후 가져옴), 404(가져올 게 없음) 상태 코드로 온 응답을 캐싱할 수 있습니다.

 

js, css, 이미지 같은 정적 컨텐츠는 데이터양이 크고,

변경될 일이 적어서 반복해서 동일한 요청을 보낼 필요가 없습니다.

정적 컨텐츠를 요청하고 나면 브라우저에서는 요청을 캐시해두고,

동일한 요청이 발생할 때 서버로 요청을 보내지 않고 캐시된 데이터를 사용합니다.

그래서 프론트엔드 개발을 하다보면 정적 컨텐츠가 캐시되어

컨텐츠를 변경해도 내용이 바뀌지 않는 경우가 종종 발생합니다.

이 때는 브라우저의 캐시를 지워주면 다시 컨텐츠를 조회하기 위해 서버로 요청을 보내게 됩니다.

 

#html

<form action="{% url 'result' %}">
    <textarea cola="40" rows="10" name="totaltext"></textarea>

#views.py

def result(request):
    full_text = request.GET['totaltext']

Post 방식

POST는 리소스를 생성/변경하기 위해 설계되었기 때문에

GET과 달리 전송해야될 데이터를 HTTP 메세지의 Body에 담아서 전송합니다.

 

HTTP 메세지의 Body는 길이의 제한없이 데이터를 전송할 수 있습니다.

그래서 POST 요청은 GET과 달리 대용량 데이터를 전송할 수 있습니다. 

이처럼 POST는 데이터가 Body로 전송되고 내용이 url을 통해 보이지 않아

GET보다 보안적인 면에서 안전하다고 생각할 수 있습니다.

하지만 POST 요청도 크롬 개발자 도구, Fiddler와 같은 툴로 요청 내용을 확인할 수 있기 때문에

민감한 데이터의 경우에는 반드시 암호화해서 전송해야 합니다.

개발자 도구에서 data를 볼 수 있음!

그리고 POST로 요청을 보낼 때는 요청 헤더의 Content-Type에 요청 데이터의 타입을 표시해야 합니다.

데이터 타입을 표시하지 않으면 서버는 내용이나 URL에 포함된 리소스의 확장자명 등으로 데이터 타입을 유추합니다. 만약, 알 수 없는 경우에는 application/octet-stream로 요청을 처리합니다.

 

#html

<form action="{% url 'result' %}" method="POST">
    {% csrf_token %}
    <textarea cola="40" rows="10" name="totaltext"></textarea>

쟝고에서는 post를 사용할 때, 보안상의 이유로 csrf_token을 반드시 사용하게 합니다.

 

 

#views.py

def result(request):
    full_text = request.POST['totaltext']

쟝고에서 Get이외의 방식으로 처리할 때는 csrf token를 넣어주어야 합니다.

장고에서는 기본적으로 csrf 공격에 대해 대응을 하고 있기 때문입니다.

그래서 유효한 토큰인지를 확인하고 데이터를 추가하거나 변경시키려는 요청을 받아줍니다. 

(장고의 1.2 버전 이후부터는 form으로 post요청을 보낼때 csrf를 검사한다.)

 

GET vs POST

GET POST
URL 노출되어도 상관없는 검색 및 조회 등을 할 때 자주 쓰임. URL 노출되면 안되는 로그인, 회원가입 등의 상황에서 자주 쓰임.
데이터 값을 바꾸지 않는 조회 등 서버 상의 데이터 값이나 상태를 바꾸기 위한 글쓰기, 글수정 등.
 Idempotent하도록 설계되어, GET으로 서버에게 동일한 요청을 여러 번 전송하더라도 동일한 응답이 돌아와야 한다는 것을 의미합니다. 이에 따라 GET은 설계원칙에 따라 서버의 데이터나 상태를 변경시키지 않아야 Idempotent하기 때문에 주로 조회를 할 때에 사용해야합니다. 예를 들어, 브라우저에서 웹페이지를 열어보거나 게시글을 읽는 등 조회를 하는 행위는 GET으로 요청하게 됩니다. Non-idempotent로 설계되었기 때문에 서버에게 동일한 요청을 여러 번 전송해도 응답은 항상 다를 수 있습니다. 이에 따라 POST는 서버의 상태나 데이터를 변경시킬 때 사용됩니다. 게시글을 쓰면 서버에 게시글이 저장이 되고, 게시글을 삭제하면 해당 데이터가 없어지는 등 POST로 요청을 하게 되면 서버의 무언가는 변경되도록 사용됩니다. 이처럼 POST는 생성, 수정, 삭제에 사용할 수 있지만, 생성에는 POST, 수정은 PUT 또는 PATCH, 삭제는 DELETE가 더 용도에 맞는 메소드라고 할 수 있습니다.
GET은 URL에 요청 파라미터를 가지고 있기 때문에 링크를 걸 때, URL에 파라미터를 사용해 더 디테일하게 페이지를 링크할 수 있습니다. 웹페이지를 조회할 때, 링크를 통해 특정 페이지로 바로 이동하려면 해당 링크와 관련된 정보가 필요한데 POST는 요청 데이터가 Body에 담겨 있기 때문에 링크 정보를 가져올 수 없습니다.
   

 

(참고: https://hongsii.github.io/2017/08/02/what-is-the-difference-get-and-post/)

댓글