블로그 목록으로

301과 302 리다이렉트, 무엇이 어떻게 다른가

영구 이동(301·308)과 임시 이동(302·307)이 브라우저 캐싱과 클릭 집계에 어떤 차이를 만드는지, 그리고 언제 어느 쪽을 골라야 하는지 정리합니다.

주소를 바꿨는데 예전 링크가 그대로 살아 있어야 할 때, 또는 한 링크가 상황에 따라 다른 곳으로 가야 할 때 쓰는 것이 리다이렉트입니다. 같은 "다른 주소로 보낸다"라도 어떤 상태 코드로 보내느냐에 따라 브라우저의 행동이 완전히 달라집니다. 301302의 차이를 알아두면 링크가 왜 기대와 다르게 동작하는지, 클릭 수가 왜 안 잡히는지를 설명할 수 있습니다.

리다이렉트는 무슨 일을 하나요

브라우저가 어떤 주소를 요청하면 서버는 응답에 상태 코드를 붙여 돌려줍니다. 200은 "여기 내용이 있다", 404는 "그런 건 없다"라는 뜻입니다. 3으로 시작하는 코드는 "그 내용은 여기 말고 다른 곳에 있다"라는 의미이고, 함께 Location 헤더에 새 주소를 담아 보냅니다.

흐름은 짧습니다.

  1. 브라우저가 A 주소를 요청합니다.
  2. 서버가 301 또는 302와 함께 "진짜 주소는 B"라고 응답합니다.
  3. 브라우저가 곧바로 B를 다시 요청합니다.
  4. B200으로 실제 내용을 돌려줍니다.

사용자 눈에는 한 번의 클릭으로 보이지만, 그 사이에 요청이 두 번 오간 셈입니다. 단축 링크가 하는 일이 바로 이 중간 단계입니다. 짧은 코드 주소를 받아서, 원본 주소로 가라고 리다이렉트로 안내합니다.

영구 이동과 임시 이동

리다이렉트는 크게 두 부류로 나뉩니다. 핵심은 "이 이동이 앞으로도 계속 유지되느냐"입니다.

  • 영구(301, 308) — "이 주소는 영원히 저쪽으로 옮겨졌다"라는 선언입니다. 브라우저는 이 정보를 믿고 캐시에 저장해 둡니다.
  • 임시(302, 307) — "지금은 저쪽으로 가지만, 다음에 또 물어봐 달라"라는 뜻입니다. 브라우저는 결과를 캐시하지 않고 매번 원래 주소에 다시 묻습니다.

이 둘의 차이는 검색엔진에서도 드러납니다. 301을 받으면 검색엔진은 기존 주소의 평가를 새 주소로 옮기고 색인을 갈아치웁니다. 302는 원래 주소를 그대로 두고 임시 우회로만 인식합니다. 그래서 페이지를 완전히 이사 보낼 때는 301, 잠깐만 돌려보낼 때는 302가 맞습니다.

캐시된 301이 클릭을 삼키는 이유

301의 캐싱은 보통 장점입니다. 한 번 "여긴 영구히 저쪽"이라고 배운 브라우저는 다음부터 서버에 묻지 않고 곧장 B로 갑니다. 왕복이 한 번 줄어 빨라집니다.

문제는 단축 링크처럼 중간에서 클릭을 세야 하는 경우입니다. 단축 서비스는 브라우저가 짧은 주소에 들를 때마다 그 방문을 기록합니다. 그런데 첫 요청에 301을 돌려주면, 브라우저는 그 사실을 캐시하고 두 번째부터는 단축 서비스를 건너뜁니다. 같은 사람이 같은 링크를 다섯 번 눌러도 서버에는 한 번만 닿습니다. 나머지 네 번의 클릭은 기록될 기회조차 얻지 못합니다. 게다가 한 번 캐시된 301은 만료되기 전까지 서버가 손쓸 방법이 없어서, 나중에 목적지를 바꾸고 싶어도 그 브라우저는 한동안 옛 주소로만 갑니다.

302는 이 함정을 피합니다. 임시 이동이므로 브라우저는 결과를 캐시하지 않고 매번 단축 서비스를 거칩니다. 덕분에 모든 클릭이 빠짐없이 집계되고, 목적지를 바꾸면 다음 클릭부터 곧바로 반영됩니다. Linkpado가 모든 단축 링크를 302로 응답하는 이유가 여기 있습니다. 캐시된 301이었다면 반복 클릭이 누락돼 방문 수가 실제보다 적게 잡힙니다.

그래서 어느 쪽을 써야 하나요

선택의 기준은 단순합니다.

  • 페이지나 도메인을 영영 옮겼고, 검색 평가까지 새 주소로 넘기고 싶다면 301을 쓰세요. 사이트 개편이나 주소 변경이 대표적입니다.
  • 링크를 측정하거나 나중에 바꿔야 한다면 302를 쓰세요. 캠페인 링크, 단축 링크, A/B 테스트처럼 클릭을 세거나 목적지를 갈아끼울 여지가 있는 경우입니다.

코드 한 가지가 더 있습니다. 307308은 각각 302, 301의 사촌으로, 요청 메서드를 그대로 보존한다는 점이 다릅니다. 원래 301·302는 일부 브라우저가 POST 요청을 GET으로 바꿔 다시 보내는 관행이 있었는데, 307·308은 POST는 POST로, GET은 GET으로 메서드를 유지하도록 명확히 규정합니다. 그래서 폼 전송 같은 요청을 리다이렉트할 때 의미가 있습니다. 단순히 링크를 다른 페이지로 보내는 경우라면 301302로 충분합니다.

정리하면, 영구 이동에는 301(메서드 보존이 필요하면 308), 임시 이동과 측정에는 302(메서드 보존이 필요하면 307)입니다. 단축 링크는 거의 항상 후자에 해당합니다. 직접 링크를 만들어 어떻게 동작하는지 보고 싶다면 홈에서 바로 시도해 볼 수 있습니다.