리다이렉트는 서버가 '원하는 리소스는 다른 위치에 있으니 그리로 다시 요청하라'고 지시하는 3xx 응답입니다. 응답의 Location 헤더에 새 URL이 담기고, 브라우저나 클라이언트가 그 URL로 자동으로 다시 요청합니다. 겉보기엔 단순하지만, 어떤 코드를 쓰느냐에 따라 재요청 시 HTTP 메서드와 본문이 보존되는지가 달라지고 SEO에도 영향을 줍니다.
GET /old-page HTTP/1.1
Host: example.com
HTTP/1.1 301 Moved Permanently
Location: https://example.com/new-page
영구 vs 임시: 301 / 302
301 Moved Permanently는 리소스가 영구적으로 옮겨졌음을 뜻합니다. 검색 엔진은 이를 보고 색인을 새 URL로 갱신하고, 링크 가치(link equity)의 대부분을 새 주소로 넘깁니다. 브라우저는 301을 공격적으로 캐시하므로, 실수로 잘못된 301을 배포하면 되돌리기가 까다롭습니다. 302 Found는 임시 이동으로, 원래 URL이 여전히 정본임을 뜻하고 검색 색인은 원래 URL을 유지합니다.
메서드 보존의 함정: 302 / 303 / 307 / 308
역사적으로 302는 규격이 모호해서, 많은 클라이언트가 원래 POST 요청을 리다이렉트 후 GET으로 바꿔 버렸습니다. 이 혼란을 정리하기 위해 명확한 코드가 추가되었습니다.
- 303 See Other: 리다이렉트 후 항상
GET으로 바꿔 재요청.POST처리 결과 페이지로 보낼 때 쓰는 전형적 패턴(PRG, Post/Redirect/Get). - 307 Temporary Redirect: 임시 이동이면서 메서드와 본문을 그대로 보존. 원래가
POST였으면 새 URL에도 본문까지POST로 다시 보냄. - 308 Permanent Redirect: 영구 이동이면서 메서드·본문 보존. 301의 '메서드 보존' 버전.
- 정리: 301/308 = 영구, 302/307 = 임시. 307/308 = 메서드 보존, 303 = 무조건 GET 전환, 301/302 = 클라이언트마다 제각각(POST가 GET으로 바뀔 수 있음).
실무 규칙은 간단합니다. 메서드가 반드시 보존돼야 하는 API 리다이렉트에는 307/308을, 사람이 보는 웹 페이지의 영구 이동에는 301을, 폼 제출 후 결과 페이지로 보낼 때는 303을 쓰세요.
SEO와 링크 가치
검색 관점에서 리다이렉트 코드 선택은 중요합니다. 도메인 이전이나 URL 구조 변경처럼 영구적인 변화에는 301(또는 308)을 써야 검색 엔진이 기존 페이지의 순위·백링크 가치를 새 URL로 이전합니다. 임시 프로모션 페이지처럼 나중에 원래 주소로 돌아올 것이라면 302를 씁니다. 코드를 잘못 고르면 축적한 검색 순위를 잃거나, 옛 URL이 계속 색인에 남는 문제가 생깁니다.
체인과 루프
리다이렉트가 또 다른 리다이렉트를 가리키면 리다이렉트 체인이 됩니다(예: http:// → https:// → https://www.). 체인은 매 홉마다 왕복이 추가돼 속도를 떨어뜨리고 링크 가치도 조금씩 희석되므로, 가능하면 최종 목적지로 한 번에 보내는 것이 좋습니다. 더 나쁜 것은 A가 B로, B가 다시 A로 보내는 리다이렉트 루프입니다. 이 경우 클라이언트는 무한 반복을 감지하고 ERR_TOO_MANY_REDIRECTS 같은 오류로 중단합니다. http↔https나 www 유무 설정이 서로 충돌할 때 흔히 발생합니다.
마지막으로 Location 헤더의 값은 절대 URL이든 상대 URL이든 허용되지만(현대 명세는 상대 URL도 허용), 예측 가능성을 위해 절대 URL을 쓰는 것이 안전합니다. 그리고 리다이렉트 응답에 본문을 담아도 대부분 무시되므로, 실제 콘텐츠는 목적지 URL이 제공해야 합니다.