본문 바로가기

programming/Web

HTTP 헤더 총정리

헤더란? HTTP 통신의 일부

 

[공통 헤더]

요청 과 응답에 모두 사용되는 헤더, Content 시리즈는 엔티티 헤더라고 불린다.

(예시 사진에 안나와 있는 헤더도 있음)

  • Date : HTTP 메시지가 만들어진 시각, 자동으로 생성됨
  • Connection : HTTP/2 -> 없음, HTTP/1.1 -> keep-alive
  • Cache-Control : 캐시 관련 헤더***********(매우 중요 - 웹성능을 최대로 높이기위해, 원하는 시점에 캐싱을 하고, 지우고가 중요, 불필요한 통신을 하지 않도록), 아래 옵션들 속성해서 사용 가능
    • no-store  : 아무것도 캐싱하지 않음, 저장하지 않음
    • no-cache : 모든 캐시를 쓰기 전에 서버에 이 캐시 써도 돼? 물어봐라 라는 뜻 = max-age:0으로 설정한 경우 / 캐시를 저장은 하지만, 바로 만료가 된 상태라서, 재검증이 필요함
      • Pragma : 동일 역할의 HTTP1.0의 헤더
      • Pragma : no-cache  = Cache-Control : no-cache 와 동일, 캐시가 캐시복사본을 릴리즈 하기 전에 원격 서버로 요청을 날려서 유효성 검사를 받도록 한다. 
    • must-revalidate : 만료된 캐시만 서버에 확인 받으렴
    • public, private : public -> CDN 같은 중간서버포함 모든사람이 캐시가능 / private -> 브라우저만(사람) 캐시가능
    • s-maxage: CDN같은 중간서버에만 적용되는 캐시 유효시간
    • public, max-age = 3600 : 캐시 유효시간, 초단위 -> Expires 헤더로도 설정가능

StatusCode에서 (from memory cache) 확인 -> max-age 만료전에 요청시 (이미지 출처: 토스테크블로그)

  • Content-length : 요청과 응답 메시지의 본문의 크기를 바이트 단위로 표시, 자동으로 생성됨
  • Content-Type : 컨텐츠타입; 문자열인코딩 명시, 응답의 Accept 헤더 시리즈와 대응됨,
    • Content-Type : text/html; charset=utf-8
      • 최초 페이지 로드시(html 문서를 읽어올 때)

 

  • Content-Type : application/json; charset-UTF-8

요청 헤더와 전송 정보
응답 헤더와 응답 정보

 

  • Content-Type : multipart/form-data; boundardy=hello -> 모든 문자를 인코딩 하지 않음, hello라는 문자열을 기준으로 전송되는 파일의 데이터를 자름, 바이너리 파일 전송시 사용
    • -- 로 시작하는 문자열인 boundary로 구분되는 서로 다른 파트들로 구성
// Ant-Design을 사용한 Form 소스코드, encType에 multipart/form-data로 명시
// content와 image를 전송하는 폼

<Form style={{ margin : '10px 0 20px'}} encType='multipart/form-data' onFinish ={onSubmit}>
    <Input.TextArea
        value={text}
        onChange={onChangeText}
        maxLength={140}
        placeholder="어떤 일이 있었나요?"
    />
    <div>
        <input type="file" name="image" multiple hidden ref={imageInput} onChange={onChangeImages}/>
        <Button onClick={onClickImageUpload} >이미지 업로드</Button>
        <Button type='primary' style={{ float: 'right'}} htmlType='submit' loading={addPostLoading}>짹짹저장</Button>
    </div>
    {/* 이미지 미리보기 */}
    <div>
        {imagePaths.map((v, i)=>(
            <div key={v} style= {{ display: 'inline-block'}}>
                <img src={`http://localhost:3065/${v}`} style={{width:'200px'}} alt={v}/> 
                <div>
                    <Button onClick={onRemoveImage(i)}>제거</Button>
                </div>
            </div>
        ))}
    </div>
</Form>

multipart/form-data 헤더와 페이로드에서 boundary의 역할

  • Content-Type : application/x-www-form-urlencoded; charset=UTF-8 -> default 값으로, 모든 문자들을 서버로 보내기 전에 인코딩 됨, 일반적인 html form태그, 바디 형태 : key=value&key2=value2
// 예시코드 "/test" 라는 없는 url로 전송 테스트

<form action="/test" method="post">
    <div>
        <input type="text" name="name" id="name" required />
    </div>
    <div>
        <input type="text" name="email" id="email" required />
    </div>
    <div>
        <input type="submit" value="Subscribe!" />
    </div>
</form>

헤더와 페이로드 데이터 형식

  • 둘다 form 형태이지만, x-www-form-urlencoded는 대용량 바이너리 데이터 전송을 하기에 비효율적이라서 대부분 첨부파일은 multipart/form-data 사용
  • Content-language : 사용자의 언어
  • Content-Encoding : 압축 방식 (ex) gzip, deflate), 브라우저가 알아서 해제해서 사용한다. 컨텐츠 용량이 줄어들기 때문에 권장, 요청이나 응답 전송속도 향상, 데이터 소모량도 감소
  • Expires : 응답 컨텐츠 만료 시간, Cache-Control : max-age 가 있는 경우 이 헤더는 무시된다.
  • ETag : HTTP 컨텐츠가 바뀌었는지 검사할 수 있는 태그, 같은 주소의 자원이더라도 컨텐츠가 달라지면 ETag가 바뀐다.

 

 

 

[요청헤더]

(예시 사진에 안나와 있는 헤더도 있음)

  • Host : 서버의 도메인네임:포트
  • User-Agent : 현재 사용자가 어떤 클라이언트로 요청을 보냈는지(운영체제 + 브라우저 정보 담겨있음)
  • Accept 시리즈 : 요청시 이런 타입의 데이터를 보내주렴 하고 명시하는 것,
    • Accept : text/html
    • Accept : image/png, image/gif
    • Accept : text/*
    • Accept-Charset : utf-8
    • Accept-Language : ko, en-US,
    • Accept-Encoding : br, gzip, deflate
  • Authentication : 토큰종류(Basic/Bearer) + 토큰문자열
  • Origin : POST 요청시 요청이 어느 주소에서 시작된 것인지, 요청을 보낸 주소와 받는 주소가 다르면 CORS문제 발생
  • Referer : 이전 페이지의 주소, 통계분석에 많이 사용된다, 어디로부터 우리 페이지에 접속했는지?
  • If-None-Match : 서버보고 ETag가 달라졌는지 확인해보고, 달라졌으면 새로 보내달라는 뜻, ETag 가 같으면 서버는 304 Not Modifed를 응답하여 캐시를 그대로 사용
  • If-Modified-Since : 캐시된 리소스의 Last-Modified 값 이후에 서버 리소스가 수정되었는지 확인한다.
    • 만료된 캐시의 경우 전체 새로 받아오는 것이 아니라, 수정이 있었는지만 판단한다
    • ETag -> If-None-Match & Last-Modified -> If-Modified-Since 판단하여 변화없으면 304 로 적은 리소스 통신, 변화 있으면 새로 내려주고 성공시 200 (많은/정상적 리소스 통신)

이미지 출처 : 토스테크블로그

  • Cookie : 반대로 클라이언트가 서버한테 쿠키를 보낼때는 여기에 담아서 요청을 보냄, 서버는 이 쿠키값을 파싱해서 사용한다. CSRF 공격같은 것을 막기 위해서 반드시 서버는 쿠키가 제대로 된 상황에서 온 것인지를 확인하는 로직을 갖춰야한다.

 

(배경지식) 캐시의 위치

- 캐시가 저장되는 곳은 여러곳 이다. 사용자의 브라우저 일 수 도 있고, 중간 서버를 사용하는 경우는 중간 서버에도 캐시가 될 수 있다. 

- 서비스를 제공하는 입장에서는, 브라우저 캐시기준, 중간서버 캐시기준을 각각 따로 민감하게 설정할 필요가 있다.

- CDN Invalidation : 중간서버에 있는 캐시를 없애는 작업. 

  - max-age = 0 으로 사용자 브라우저는 매번 요청마다 리소스에 변화가 있었는지 재검증을 받는다

  - s-maxage = 31536000 으로 중간서버는 1년(대략)에 한번씩 재검증을 받는다. 대신 그 사이에 서비스 새로운 배포가     있었다면 CDN Invalidation 을 발생시켜 CDN이 새로운 버전을 캐시해 두도록 한다.

이미지출처 : 토스테크블로그

 

[응답 헤더]

  • Access-Control-Allow-Origin : 프론트주소와 백엔드 주소가 다르면 CORS 에러발생, 서버에서 이 헤더에 프론트 주소를 적어주어야 에러가 나지 않는다. CORS 요청시 OPTIONS 주소로 서버가 CORS를 허용하는지 물어본다. 이때 아래의 request-allow 짝꿍이 맞으면 CORS 요청이 이루어진다.
    • Access-Control-Request-Method, : 실제로 보내려는 메서드를 알림
    • Access-Control-Request-Headers, : 실제로 보내려는 헤더를 알림
    • Access-Control-Allow-Methods, : 받아도 되는 메서드 명시
    • Access-Control-Allow-Headers : 받아도 되는 헤더 명시 
  • Allow : Access-Control-Allow-Method 와 비슷하지만, CORS 요청 외에도 적용된다는 데 차이가 있다.
  • Content-Disposition : 응답 본문을 브라우저가 어떻게 표시해야하 할지 알려주는 헤더, inline은 웹페이지 화면에 표시되고, attechment인 경우 다운로드한다.
  • Location : 300번대 응답이나, 201 created 응답일때 어느 페이지로 이동할지 알려주는 헤더
  • Content-Security-Policy : 다른 외부 파일들을 불러오는 경우, 차단할 소스와 불러올 소스를 명시, 
    • Content-Security-Policy: default-src 'self' :self로 지정하면 자신의 도메인의 파일들만 가능
    • Content-Security-Policy: default-src https: :https로 지정시 https 통해서만 가져올 수 있음
    • Content-Security-Policy: default-src 'none' : 외부 파일 가져오기 불가
  • Set-Cookie : 키=밸류, 서버에서 클라이언트(브라우저) 한테 어떤 쿠키를 저장할지 명령
    • ex) Set-Cookie: zerocho=babo; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Secure; HttpOnly

 

Content-Type : application/x-www-form-urlencoded
Content-Type : multipart/form-data
두개의 차이점은?

form 데이터를 전송한다는 맥락은 동일,
application/x-www-form-urlencoded는 default 값으로 html <form> 태그를 사용한 제출시 사용되는 content-type 이다. 전송되는 데이터의 형태는 키=밸류&키=밸류 

multipart/form-data는 이미지파일과같은 바이너리 파일들을 함께 전송할때 사용
boundary의 역할은 위에서 & 랑 비슷, 각각의 요소들의 바운더리를 의미함.

 

 

참고

https://toss.tech/article/smart-web-service-cache

 

웹 서비스 캐시 똑똑하게 다루기

웹 성능을 위해 꼭 필요한 캐시, 제대로 설정하기 쉽지 않습니다. 토스 프론트엔드 챕터에서 올바르게 캐시를 설정하기 위한 노하우를 공유합니다.

toss.tech

https://devowen.com/275

 

[TroubleShooting] Content-type: x-www-form-urlencoded에서 POST 데이터 보내기

오늘은 최근에 내가 개발을 하면서 몇 시간동안 고민한 이슈에 대한 정리를 해 보려고 한다. 이 이슈는 내가 어떤 회사에 입사하기 위해 치뤘던 코딩 과제를 하는 도중에 발생하였다. 다행히도

devowen.com

https://neph3779.github.io/%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC/HTTPBasicWithSwift/

 

HTTP 기본 개념 정리 with swift - Neph's iOS blog

HTTP란?

neph3779.github.io