·HTTP 코드와 헤더

HTTP 상태 코드와 헤더 132가지

404와 500이 무슨 뜻인지, Content-Type과 Cache-Control이 무엇을 하는지 한 줄로 정리했습니다.

상태 코드

1xx 정보4

아직 진행 중이라는 알림입니다. 최종 응답이 뒤따릅니다.

2xx 성공10

요청이 제대로 처리됐다는 뜻입니다.

3xx 넘김8

다른 곳으로 가라는 뜻입니다. 영구인지 임시인지가 갈립니다.

4xx 요청 잘못29

요청 쪽에 문제가 있다는 뜻입니다. 같은 요청을 그대로 보내면 또 실패합니다.

400 Bad Request요청 자체가 잘못돼 읽을 수 없다는 뜻입니다.401 Unauthorized누구인지 밝히지 않았다는 뜻입니다. 로그인하면 풀립니다.402 Payment Required결제가 필요하다는 뜻입니다. 표준에는 있지만 실제로는 드물게 쓰입니다.403 Forbidden누구인지는 알지만 권한이 없다는 뜻입니다. 로그인해도 그대로일 수 있습니다.404 Not Found그 주소에 아무것도 없다는 뜻입니다. 주소가 틀렸거나 이미 지워진 것입니다.405 Method Not Allowed그 주소는 있지만 그 방식은 받지 않는다는 뜻입니다.406 Not Acceptable요청한 형식으로는 줄 수 없다는 뜻입니다.407 Proxy Authentication Required중간 서버가 먼저 인증을 요구한다는 뜻입니다.408 Request Timeout기다렸는데 요청이 끝까지 오지 않았다는 뜻입니다.409 Conflict지금 상태와 부딪혀 처리할 수 없다는 뜻입니다. 동시에 고칠 때 납니다.410 Gone일부러 지웠고 다시 오지 않는다는 뜻입니다. 404보다 분명한 작별입니다.411 Length Required본문 길이를 밝히지 않았다는 뜻입니다.412 Precondition Failed붙여 보낸 조건이 맞지 않았다는 뜻입니다.413 Content Too Large보낸 본문이 서버가 받는 크기를 넘었다는 뜻입니다.414 URI Too Long주소가 너무 길다는 뜻입니다. 쿼리를 지나치게 붙였을 때 납니다.415 Unsupported Media Type보낸 본문의 형식을 다룰 수 없다는 뜻입니다.416 Range Not Satisfiable요청한 범위가 파일 밖이라는 뜻입니다.417 Expectation FailedExpect 헤더에 적은 기대를 맞출 수 없다는 뜻입니다.418 I'm a teapot커피를 끓여 달라는 요청을 찻주전자가 거절한다는 농담 코드입니다.421 Misdirected Request이 서버가 받을 요청이 아니라는 뜻입니다.422 Unprocessable Content형식은 맞지만 내용이 규칙에 어긋나 처리할 수 없다는 뜻입니다.423 Locked그 자원이 잠겨 있다는 뜻입니다.424 Failed Dependency앞선 요청이 실패해 이 요청도 못 한다는 뜻입니다.425 Too Early다시 보낼 위험이 있어 아직 처리하지 않는다는 뜻입니다.426 Upgrade Required다른 프로토콜로 올려야 이어갈 수 있다는 뜻입니다.428 Precondition Required조건을 붙여 보내야 한다는 뜻입니다. 덮어쓰기 사고를 막으려는 것입니다.429 Too Many Requests너무 자주 요청했다는 뜻입니다. Retry-After에 다시 시도할 시간이 담깁니다.431 Request Header Fields Too Large헤더가 너무 크다는 뜻입니다. 쿠키가 쌓였을 때 납니다.451 Unavailable For Legal Reasons법적인 이유로 막혔다는 뜻입니다. 번호는 소설 화씨 451도에서 왔습니다.

5xx 서버 잘못11

서버 쪽에 문제가 있다는 뜻입니다. 잠시 뒤 다시 시도해 볼 만합니다.

헤더

요청 헤더55

브라우저가 서버에 보낼 때 붙이는 헤더들입니다.

Accept어떤 형식으로 받고 싶은지 알립니다.Accept-Encoding압축 방식을 알립니다. gzip이나 br을 쓰면 전송량이 크게 줄어듭니다.Accept-Language원하는 언어를 알립니다. 여러 언어 사이트가 이 값을 보고 고릅니다.Authorization신원을 증명하는 값입니다. 토큰이나 아이디·비밀번호가 담깁니다.Cookie앞서 서버가 심어 둔 쿠키를 도로 보냅니다.Host어느 도메인에 보내는 요청인지 밝힙니다. 한 서버가 여러 사이트를 담을 수 있게 합니다.If-Modified-Since그 시각 이후에 바뀌었을 때만 달라는 뜻입니다.If-None-Match가진 ETag와 다를 때만 달라는 뜻입니다. 캐시가 이렇게 확인합니다.Origin요청을 보낸 출처를 알립니다. 브라우저가 붙이며 CORS 판단의 기준이 됩니다.Range파일의 일부만 달라는 뜻입니다. 이어받기와 영상 탐색이 이걸로 됩니다.Referer어느 페이지에서 눌러 왔는지 알립니다. 철자가 틀린 채로 표준이 됐습니다.User-Agent어떤 브라우저와 기기인지 알립니다. 지금은 대부분 비슷하게 위장돼 있습니다.Sec-Fetch-Dest그 요청이 무엇에 쓰일지 알립니다. 그림인지 스크립트인지 같은 것입니다.Sec-Fetch-Mode요청 방식이 같은 출처인지 CORS인지 알립니다.Sec-Fetch-Site요청이 같은 사이트에서 왔는지 다른 사이트에서 왔는지 알립니다.DNT추적하지 말라는 요청입니다. 강제력이 없어 대부분 무시됩니다.Expect본문을 보내기 전에 서버가 받을지 먼저 묻습니다.Forwarded중간을 거친 요청의 원래 정보를 담습니다.From요청을 보낸 사람의 이메일을 담습니다. 크롤러가 연락처로 씁니다.If-Match가진 ETag와 같을 때만 처리하라는 뜻입니다. 덮어쓰기 사고를 막습니다.If-Range조건이 맞으면 이어받고, 아니면 처음부터 받겠다는 뜻입니다.Max-Forwards중간 서버를 몇 번까지 거칠지 정합니다.Proxy-Authorization중간 서버에 내는 인증 정보입니다.TE전송 중에 어떤 인코딩을 받아들일지 알립니다.Upgrade-Insecure-Requestshttp로 걸린 링크도 https로 바꿔 달라는 요청입니다.X-Forwarded-For중간을 거친 요청의 원래 IP를 담습니다. 표준은 아니지만 널리 쓰입니다.X-Forwarded-Proto원래 요청이 http였는지 https였는지 알립니다.X-Requested-With자바스크립트가 보낸 요청임을 알리던 옛 관행입니다.Accept-Charset클라이언트가 받을 수 있는 문자 인코딩을 알립니다. 지금은 거의 쓰지 않습니다.If-Unmodified-Since그 시각 이후로 바뀌지 않았을 때만 처리하라고 합니다. 덮어쓰기 사고를 막습니다.Sec-CH-UA브라우저의 이름과 큰 판 번호를 알립니다. User-Agent를 대신하려고 만든 것입니다.Sec-CH-UA-Mobile손전화인지 아닌지만 알립니다. 참·거짓 한 칸입니다.Sec-CH-UA-Platform어떤 운영체제에서 왔는지 알립니다. 판 번호는 따로 물어야 합니다.Save-Data데이터를 아끼고 싶다는 뜻을 서버에 전합니다. 가벼운 판을 내려 줄 수 있습니다.Device-Memory기기의 대략적인 메모리 크기를 알립니다. 값은 뭉뚱그려 보냅니다.Early-Data아직 완전히 안전하지 않은 이른 데이터로 보냈다는 표시입니다.Access-Control-Request-Method본 요청에서 쓸 방식을 미리 묻습니다. 사전 요청에만 붙습니다.Access-Control-Request-Headers본 요청에서 붙일 헤더를 미리 묻습니다. 사전 요청에만 붙습니다.Sec-Purpose이 요청이 미리 받아 두는 것인지 알립니다. prefetch면 사용자가 아직 안 눌렀다는 뜻입니다.Sec-CH-UA-Arch기기의 CPU 구조를 알립니다. arm과 x86 가운데 무엇인지 서버가 알 수 있습니다.Sec-CH-UA-Model기기 모델 이름을 알립니다. 실제로 값이 실리는 것은 거의 휴대전화뿐입니다.Sec-CH-UA-Platform-Version운영체제의 판 번호를 알립니다. Sec-CH-UA-Platform과 짝을 이룹니다.X-Forwarded-Host프록시를 거치기 전에 브라우저가 적었던 원래 호스트 이름입니다.X-Real-IP프록시가 원래 접속자의 주소를 적어 넘깁니다. 표준은 아니지만 널리 쓰입니다.Alt-UsedAlt-Svc를 보고 다른 서버로 옮겨 왔음을 알립니다. 순환을 막는 데 씁니다.Sec-WebSocket-Key웹소켓으로 바꿔 달라며 보내는 무작위 값입니다. 서버가 이 값을 가공해 되돌려 줍니다.Sec-WebSocket-Version쓰려는 웹소켓 규격의 판 번호입니다. 지금은 13이 사실상 유일합니다.Last-Event-ID끊긴 서버 전송 이벤트를 이어 받을 때 마지막으로 받은 번호를 알립니다.Traceparent한 요청이 여러 서비스를 지나갈 때 그 흐름을 잇는 추적 번호입니다.Baggage요청을 따라다니며 서비스들이 함께 읽는 이름표를 실어 나릅니다.Idempotency-Key같은 요청이 두 번 도착해도 한 번만 처리되게 하는 열쇠입니다. 결제에서 많이 씁니다.Prefer서버에 "이렇게 해 주면 좋겠다"고 바람을 전합니다. 지켜도 되고 안 지켜도 됩니다.Sec-GPC개인정보를 팔거나 넘기지 말라는 뜻을 브라우저가 대신 전합니다.Sec-CH-Prefers-Color-Scheme사용자가 밝은 화면을 좋아하는지 어두운 화면을 좋아하는지 알립니다.Sec-CH-UA-Full-Version-List브라우저와 엔진의 전체 버전 목록을 알립니다. User-Agent를 대신하는 쪽입니다.

응답 헤더56

서버가 브라우저에 돌려줄 때 붙이는 헤더들입니다.

Access-Control-Allow-Origin어느 출처에서 이 응답을 읽어도 되는지 정합니다. CORS의 핵심입니다.Access-Control-Allow-Methods교차 출처 요청에 허용하는 방식들을 적습니다.Access-Control-Allow-Headers교차 출처 요청에 허용하는 헤더들을 적습니다.Access-Control-Allow-Credentials쿠키를 실어 보내는 교차 출처 요청을 허용할지 정합니다.Access-Control-Max-Age사전 요청 결과를 얼마나 오래 재사용할지 정합니다.Age이 응답이 캐시에 머문 시간입니다.Allow그 주소가 받아들이는 방식들을 알립니다. 405와 함께 옵니다.Content-Disposition화면에 열지 내려받을지 정합니다. 파일 이름도 여기에 담깁니다.Content-Security-Policy어디서 온 스크립트와 이미지를 실행·표시할지 정합니다. XSS를 막는 울타리입니다.ETag그 판의 지문입니다. 바뀌면 값이 달라져 캐시가 알아챕니다.Expires이 시각이 지나면 낡은 것으로 보라는 뜻입니다.Last-Modified마지막으로 바뀐 시각입니다. 조건부 요청의 기준이 됩니다.Location다음에 갈 주소입니다. 넘김 응답과 201에 함께 옵니다.Permissions-Policy카메라·마이크·위치 같은 기능을 어느 문서가 쓸 수 있는지 정합니다.Referrer-Policy출처 정보를 얼마나 실어 보낼지 정합니다.Retry-After언제 다시 시도하면 되는지 알립니다. 429·503과 함께 옵니다.Server응답한 서버 소프트웨어를 알립니다. 자세히 적으면 공격에 힌트가 됩니다.Set-Cookie브라우저에 쿠키를 심습니다. HttpOnly와 Secure를 붙이는 것이 안전합니다.Strict-Transport-Security앞으로 이 사이트는 https로만 오라고 브라우저에 새깁니다.Timing-Allow-Origin다른 출처가 성능 측정값을 읽어도 되는지 정합니다.Vary같은 주소라도 어떤 헤더에 따라 응답이 달라지는지 알립니다. 캐시가 이걸 보고 나눕니다.WWW-Authenticate어떤 방식으로 인증하라고 알려 줍니다. 401과 함께 옵니다.X-Content-Type-Options형식을 브라우저가 멋대로 짐작하지 못하게 막습니다.X-Frame-Options다른 사이트가 이 페이지를 프레임에 넣지 못하게 막습니다.X-XSS-Protection옛 브라우저의 XSS 필터를 켜던 헤더입니다. 지금은 CSP가 대신합니다.Cross-Origin-Opener-Policy다른 출처가 창을 붙들지 못하게 떼어 놓습니다.Cross-Origin-Resource-Policy이 자원을 어느 출처가 가져갈 수 있는지 정합니다.Cross-Origin-Embedder-Policy출처가 다른 자원을 함부로 끌어오지 못하게 합니다.Content-Range보낸 조각이 전체 어디에 해당하는지 알립니다. 206과 함께 옵니다.Accept-Ranges부분 요청을 받는지 알립니다. bytes면 이어받기가 됩니다.Accept-Patch이 주소가 받아 주는 고치기 형식을 알립니다.Accept-Post이 주소가 받아 주는 보내기 형식을 알립니다.Alt-Svc같은 내용을 더 나은 길로도 받을 수 있다고 알립니다. HTTP/3 안내에 씁니다.Clear-Site-Data저장해 둔 것을 지우라고 브라우저에 시킵니다. 로그아웃에 씁니다.Link관계 있는 다른 주소를 헤더로 알립니다. 미리 불러오기 안내에도 씁니다.NEL브라우저가 겪은 오류를 어디로 보고할지 정합니다.Report-To보고를 받을 곳의 이름과 주소를 미리 등록합니다.Server-Timing서버 안에서 어느 단계에 얼마나 걸렸는지 알려 줍니다.SourceMap묶기 전의 원래 코드가 어디 있는지 가리킵니다.X-DNS-Prefetch-Control주소 미리 찾기를 켤지 끌지 정합니다.X-Permitted-Cross-Domain-Policies플래시 같은 옛 플러그인이 이 자리 자료를 가져가도 되는지 정합니다.X-Robots-Tag검색 로봇에게 색인 방침을 헤더로 전합니다. 그림·PDF에도 걸 수 있습니다.Origin-Agent-Cluster이 출처를 다른 곳과 따로 떼어 달라고 요청합니다.Proxy-Authenticate프록시가 신분을 밝히라고 요구하는 방식을 알립니다.Access-Control-Expose-Headers스크립트가 읽어도 되는 응답 헤더를 열어 줍니다.CDN-Cache-Control중간 배달망에만 통하는 저장 규칙입니다. 브라우저는 무시합니다.Accept-CH서버가 받고 싶은 클라이언트 힌트를 알립니다. 다음 요청부터 그 값이 실립니다.Critical-CH그 힌트가 없으면 페이지를 다시 받아야 한다고 알립니다. 첫 요청을 한 번 더 돌립니다.Reporting-Endpoints오류 보고를 보낼 주소를 정합니다. 옛 Report-To를 대신합니다.X-Powered-By서버가 쓰는 기술 이름을 드러냅니다. 알려 봐야 득이 없어 지우는 것이 보통입니다.X-CacheCDN이 저장해 둔 것으로 답했는지 알립니다. HIT면 원 서버까지 안 갔다는 뜻입니다.Refresh몇 초 뒤 다른 쪽으로 옮기라고 시킵니다. 표준에 없지만 브라우저가 다 따릅니다.Sec-WebSocket-Accept받은 열쇠를 정해진 방식으로 가공해 되돌려 줍니다. 이것이 맞아야 연결이 열립니다.Speculation-Rules브라우저가 어떤 주소를 미리 받아 둘지 규칙으로 알려 줍니다.No-Vary-Search주소의 물음표 뒤가 달라도 같은 캐시를 써도 된다고 알립니다.X-UA-Compatible옛 인터넷 익스플로러에게 어느 모드로 그릴지 알려 주던 헤더입니다.

요청·응답 공통22

요청과 응답 어느 쪽에나 붙을 수 있는 헤더들입니다.

Cache-Control얼마나 오래, 어디까지 캐시해도 되는지 정합니다. 성능의 절반이 여기서 갈립니다.Connection연결을 이어 쓸지 끊을지 알립니다. HTTP/2부터는 쓰이지 않습니다.Content-Encoding본문을 어떤 방식으로 압축했는지 알립니다.Content-Language본문이 어떤 언어로 쓰였는지 알립니다.Content-Length본문이 몇 바이트인지 알립니다.Content-Type본문의 형식과 인코딩을 알립니다. 이 값이 틀리면 이미지가 글자로 보입니다.Date메시지를 만든 시각입니다.Pragma옛 캐시 제어 헤더입니다. 지금은 Cache-Control이 대신합니다.Trailer본문 뒤에 이어 붙일 헤더 이름을 미리 알립니다.Transfer-Encoding본문을 어떤 방식으로 나눠 보내는지 알립니다. chunked면 길이를 미리 몰라도 됩니다.Upgrade다른 프로토콜로 갈아타자고 제안합니다. 101과 짝을 이룹니다.Via거쳐 온 중간 서버들을 기록합니다.Warning캐시나 변환에 관한 주의를 적던 헤더입니다. 지금은 쓰지 않습니다.Priority이 요청을 얼마나 먼저 처리할지 알립니다. 급함과 끼어들기를 함께 적습니다.Content-Location지금 보낸 내용이 실제로 어느 주소에 있는지 알립니다.Keep-Alive이어 쓰는 연결을 얼마나 오래 열어 둘지 알립니다.Content-Digest본문의 지문 값을 실어 보냅니다. 받는 쪽이 상했는지 확인할 수 있습니다.Tracestate추적 시스템마다 필요한 부가 정보를 traceparent 옆에 함께 싣습니다.Repr-Digest보낸 내용의 해시를 함께 실어, 받은 쪽이 상하지 않았는지 확인하게 합니다.Signature요청이나 응답에 붙인 서명입니다. 보낸 쪽이 맞는지 확인할 수 있습니다.Signature-Input그 서명이 무엇을 덮는지 — 어떤 헤더를 어떤 방법으로 서명했는지 적습니다.X-Request-ID요청 하나하나에 붙이는 번호입니다. 로그에서 그 요청만 찾아낼 때 씁니다.

읽는 방법

  • 상태 코드는 첫 자리가 뜻을 정합니다. 4로 시작하면 요청 쪽, 5로 시작하면 서버 쪽 문제입니다.
  • 404는 "없다", 403은 "있지만 안 된다"입니다. 둘을 바꿔 쓰면 원인을 찾는 데 시간이 더 걸립니다.
  • 헤더 이름은 대소문자를 가리지 않습니다. Content-Type과 content-type은 같은 헤더입니다.
  • 캐시와 CORS 문제는 대개 헤더 한 줄에서 갈립니다. 브라우저 개발자 도구의 네트워크 탭에서 그대로 볼 수 있습니다.

자주 묻는 질문

Q404와 403은 뭐가 다른가요?

404는 그 주소에 아무것도 없다는 뜻이고, 403은 있지만 볼 권한이 없다는 뜻입니다. 다만 자원이 있다는 사실 자체를 숨기려고 일부러 404를 주는 서버도 있습니다.

Q500 오류가 나면 제가 할 수 있는 게 있나요?

5로 시작하는 코드는 서버 쪽 문제라 대개 기다리는 것 말고 할 일이 없습니다. 다만 502·504는 앞단과 뒷단 사이의 문제라 잠시 뒤 다시 시도하면 풀리는 일이 많습니다.

Q301과 302는 어떻게 고르나요?

주소를 완전히 옮겼으면 301, 잠시만 다른 곳으로 보낼 거면 302입니다. 301은 브라우저와 검색엔진이 오래 기억하므로 되돌리기 어렵다는 점을 염두에 두세요.

Q헤더 이름은 대소문자를 가리나요?

가리지 않습니다. Content-Type과 content-type은 같은 헤더이고, HTTP/2부터는 아예 소문자로 보내도록 정해져 있습니다.

QCORS 오류는 왜 나나요?

브라우저가 다른 출처의 응답을 읽으려 할 때, 서버가 Access-Control-Allow-Origin으로 허락하지 않으면 막습니다. 서버가 응답은 보냈지만 브라우저가 읽기를 거부한 상태라, 네트워크 탭에서는 응답이 보이는데 코드에서는 못 읽는 일이 생깁니다.