301 Moved Permanently
사용법
301 Moved Permanently 상태 코드를 받으면 클라이언트는 저장해 둔 링크를 새 URI로 갱신해야 합니다. 새 URI는 Location 헤더로 지정되며, 클라이언트는 이를 사용해 자동으로 리다이렉트합니다.
이 응답은 서버가 새 도메인으로 이전하거나 내부 파일 구조를 재편하면서 이전 URI로 되돌릴 계획이 없을 때 흔히 쓰입니다.
메서드 변경
역사적인 이유로 사용자 에이전트는 301 리다이렉트에서 POST를 GET으로 바꾸는 것이 허용됩니다. 대부분의 브라우저가 실제로 그렇게 하므로, 이 메서드 변경은 사실상의 표준 동작이 되었습니다. 308 상태 코드는 모호함 없이 메서드 보존을 보장하기 위해 특별히 만들어졌습니다. API와 현대적인 애플리케이션에서는 원래 메서드를 반드시 유지해야 하는 영구 리다이렉트에 308을 선호하세요.
301 리다이렉트는 최소 1년, 가능하면 무기한 유지하세요. Google은 301을 빠르게 인식하지만 신호가 완전히 이전되기까지는 몇 주가 걸립니다. 브라우저는 Cache-Control 지시문에 따라 301 응답을 공격적으로 캐시합니다. 명시적인 캐시 헤더가 없으면 그 리다이렉트는 브라우저 캐시에 무기한 남습니다. 서버 쪽에서 301을 제거해도 브라우저에 캐시된 리다이렉트는 지워지지 않습니다.
참고
이전 URL이 콘텐츠 제공을 영구히 중단해야 한다면 301을 사용하세요. 두 URL 모두 계속 콘텐츠를 제공하지만 색인에는 한쪽이 선호될 때는 rel=“canonical”을 사용하세요. 301은 모든 트래픽을 새 URL로 강제하는 반면, canonical은 검색 엔진이 따르기는 하지만 강제되지는 않는 힌트입니다.
SEO 영향
Google은 301을 리다이렉트 대상이 선호 URL이라는 강한 신호로 취급합니다. 순위 신호는 이전 URL에서 새 URL로 이전됩니다. 영구적인 URL 변경, 도메인 이전, HTTPS 전환에는 301을 사용하세요. Google은 최대 10단계의 리다이렉트를 따라갑니다. 중간 리다이렉트 URL의 콘텐츠는 무시됩니다. 삭제된 URL을 301로 홈페이지나 일반적인 카테고리 페이지로 리다이렉트하면 Google은 이를 소프트 404로 감지합니다.
예시
클라이언트가 HTML 리소스를 요청합니다. 서버는 301 Moved Permanently로 응답하며 Location 헤더에 새 URI를 포함합니다. 메시지 본문은 북마크를 갱신하라고 안내하지만, 현대 브라우저는 즉시 리다이렉트합니다.
요청
GET /news.html HTTP/1.1
Host: example.com
응답
HTTP/1.1 301 Moved Permanently
Location: http://example.com/feeds/news.html
Content-Type: text/html; charset=UTF-8
Content-Length: 150
<h1>The Newsfeed has moved</h1>
<body>
The newsfeed has moved permanently to
<a href=/feeds/news.html>here</a>.
Please update your bookmarks.
</body>
코드 참고
.NET
HttpStatusCode.MovedPermanently
Rust
http::StatusCode::MOVED_PERMANENTLY
Rails
:moved_permanently
Go
http.StatusMovedPermanently
Symfony
Response::HTTP_MOVED_PERMANENTLY
Python3.5+
http.HTTPStatus.MOVED_PERMANENTLY
Java
java.net.HttpURLConnection.HTTP_MOVED_PERM
Apache HttpComponents Core
org.apache.hc.core5.http.HttpStatus.SC_MOVED_PERMANENTLY
Angular
@angular/common/http/HttpStatusCode.MovedPermanently