참조 : mod_rewrite, URL 재 작성 및 "pretty 링크"설명
"예쁜 링크"는 자주 요청되는 주제이지만 그에 대한 설명은 거의 없습니다. mod_rewrite는 "예쁜 링크"를 만드는 한 가지 방법이지만, 복잡하고 구문이 간결하고 이해하기 어려우며 문서는 HTTP의 특정 수준의 숙련도를 가정합니다. 누군가 "예쁜 링크"가 어떻게 작동하는지 mod_rewrite를 사용하여 어떻게 만들 수 있는지 간단한 용어로 설명 할 수 있습니까?
클린 URL에 대한 다른 일반적인 이름, 별명, 용어 : RESTful URL, 사용자 친화적 URL, SEO 친화적 URL, 슬러 깅, MVC URL (아마도 잘못된 이름)
mod_rewrite의 기능을 이해하려면 먼저 웹 서버의 작동 방식을 이해해야합니다. 웹 서버는 HTTP 요청에 응답 합니다 . 가장 기본적인 수준의 HTTP 요청은 다음과 같습니다.
GET /foo/bar.html HTTP/1.1
이것은 URL /foo/bar.html
을 요청하는 웹 서버에 대한 브라우저의 간단한 요청입니다 . 파일을 요청하지 않고 임의의 URL 만 요청한다는 점을 강조하는 것이 중요합니다 . 요청은 다음과 같습니다.
GET /foo/bar?baz=42 HTTP/1.1
이것은 URL에 대한 유효한 요청이며 파일과는 더 관련이 없습니다.
웹 서버는 포트에서 수신 대기하는 응용 프로그램으로, 해당 포트에서 들어오는 HTTP 요청을 수락하고 응답을 반환합니다. 웹 서버는 사용자가 응답하도록 구성한 방식으로 어떤 방식 으로든 요청에 응답 할 수 있습니다. 이 응답은 파일이 아니며 HTTP 응답 이므로 디스크의 실제 파일과 관련이 있거나 없을 수 있습니다. 웹 서버는 아파치 일 필요는 없으며, 지속적으로 실행되고 HTTP 요청에 응답하는 포트에 연결된 프로그램 일 뿐인 다른 많은 웹 서버가 있습니다. 직접 쓸 수 있습니다. 이 단락은 URL이 파일과 직접 동일한 개념으로 이해하기 위해 작성되었습니다. :)
대부분의 웹 서버의 기본 구성은 하드 디스크의 URL과 일치하는 파일을 찾는 것입니다. 서버 의 문서 루트 가로 설정되어 있으면 /var/www
파일 /var/www/foo/bar.html
이 존재 하는지 확인하여 파일 을 제공 할 수 있습니다. 파일이 ".php"로 끝나면 PHP 인터프리터를 호출 한 다음 결과 를 반환합니다. 이 모든 연관성을 완전히 구성 할 수 있습니다. 웹 서버가 PHP 인터프리터를 통해 파일을 실행하기 위해 파일이 ".php"로 끝나지 않아도되며 URL은 디스크의 특정 파일과 일치하지 않아도 발생합니다.
mod_rewrite는 내부 요청 처리 를 다시 쓰는 방법 입니다. 웹 서버가 URL에 대한 요청을 수신 하면 웹 서버가 디스크에서 파일과 일치하는 파일을 찾기 전에 해당 URL을 다른 것으로 다시 작성할/foo/bar
수 있습니다 . 간단한 예 :
RewriteEngine On
RewriteRule /foo/bar /foo/baz
이 규칙은 요청이 "/ foo / bar"와 일치 할 때마다 "/ foo / baz"에 다시 작성합니다. 그러면 요청이 요청 된 것처럼 처리 /foo/baz
됩니다. 다음과 같은 다양한 효과에 사용할 수 있습니다.
RewriteRule (.*) $1.html
이 규칙 일치 아무것도 ( .*
) 및 캡처는 그것을 ( (..)
), 다음은 ".html 중에서"를 추가 할 재 작성. 즉, /foo/bar
요청 된 URL 인 경우 /foo/bar.html
요청 된 것처럼 처리됩니다 . 정규식 일치, 캡처 및 대체에 대한 자세한 내용은 http://regular-expressions.info 를 참조하십시오 .
자주 발생하는 또 다른 규칙은 다음과 같습니다.
RewriteRule (.*) index.php?url=$1
이것은 다시 무엇이든 일치시키고 url
query 매개 변수 에 원래 요청 된 URL을 추가하여 index.php 파일에 다시 씁니다 . 즉, 들어오는 모든 요청에 대해 index.php 파일이 실행 되고이 파일은의 원래 요청에 액세스 $_GET['url']
할 수 있으므로 원하는 모든 작업을 수행 할 수 있습니다.
기본적으로 이러한 다시 쓰기 규칙을 웹 서버 구성 파일에 넣습니다 . 또한 아파치는 .htaccess
문서 루트 (예 : .php 파일 옆) 에있는 파일에 파일을 넣을 수 있도록합니다 * .
* 기본 Apache 구성 파일에서 허용하는 경우 선택 사항이지만 종종 사용됩니다.
mod_rewrite가하지 않는 것
mod_rewrite가 모든 URL을 마술처럼 아름답게 만들지는 않습니다. 이것은 일반적인 오해입니다. 웹 사이트에이 링크가있는 경우 :
<a href="/my/ugly/link.php?is=not&very=pretty">
mod_rewrite가 그것을 예쁘게 만들기 위해 할 수있는 일은 없습니다. 이 링크를 예쁘게 만들려면 다음을 수행해야합니다.
링크를 예쁜 링크로 변경하십시오.
<a href="/my/pretty/link">
서버에서 mod_rewrite를
/my/pretty/link
사용하여 위에서 설명한 방법 중 하나를 사용 하여 URL에 대한 요청을 처리하십시오 .
mod_substitute
나가는 HTML 페이지와 포함 된 링크를 변환하는 데 함께 사용할 수 있습니다 . HTML 리소스를 업데이트하는 것보다 일반적으로 더 많은 노력이 필요합니다.
mod_rewrite가 수행 할 수있는 작업과 여러 번의 재 작성 연결, 완전히 다른 서비스 또는 시스템에 대한 요청 프록시, 특정 HTTP 상태 코드를 응답으로 반환, 요청 리디렉션 등을 포함하여 생성 할 수있는 매우 복잡한 일치 규칙이 있습니다. 매우 강력하고 사용할 수 있습니다. 기본 HTTP 요청-응답 메커니즘을 이해하면 좋습니다. 자동으로 링크를 예쁘게 만들지 는 않습니다 .
가능한 모든 플래그 및 옵션에 대해서는 공식 문서 를 참조하십시오 .
deceze의 답변 을 확장 하기 위해 다른 mod_rewrite 기능에 대한 몇 가지 예와 설명을 제공하고 싶었습니다.
예 아래의 모든 이미 포함했다고 가정 RewriteEngine On
당신의 .htaccess
파일.
재 작성 예
이 예제를 보자.
RewriteRule ^blog/([0-9]+)/([A-Za-z0-9-\+]+)/?$ /blog/index.php?id=$1&title=$2 [NC,L,QSA]
규칙은 4 개의 섹션으로 나뉩니다.
RewriteRule
-다시 쓰기 규칙을 시작합니다^blog/([0-9]+)/([A-Za-z0-9-\+]+)/?$
-이것을 패턴이라고 부르지 만, 그냥 규칙의 왼쪽이라고하겠습니다.blog/index.php?id=$1&title=$2
-대체 규칙 또는 재 작성 규칙의 오른쪽-재 작성하려는 항목[NC,L,QSA]
다시 쓰기 규칙에 대한 플래그이며 쉼표로 구분되며 나중에 자세히 설명하겠습니다.
위의 다시 쓰기를 사용하면 비슷한 것으로 링크 할 수 /blog/1/foo/
있으며 실제로로드 /blog/index.php?id=1&title=foo
됩니다.
규칙의 왼쪽
^
페이지 이름의 시작을 나타내므로 다시example.com/blog/...
쓰지만 다시 쓰지 는 않습니다.example.com/foo/blog/...
- 각
(…)
괄호 세트 는 규칙의 오른쪽에서 변수로 캡처 할 수있는 정규식을 나타냅니다. 이 예에서 :- 첫 번째 대괄호 세트는-
([0-9]+)
길이가 최소 1 자이고 숫자 값만있는 문자열 (예 : 0-9)과 일치합니다. 이것은$1
규칙의 오른쪽에서 참조 할 수 있습니다 - 괄호의 두 번째 세트는 숫자 (AZ, az, 0-9)를 포함, 길이가 1 개 문자의 최소 문자열을 일치하거나
-
또는+
(주는+
이것은로 실행됩니다 그것을 탈출하지 않고 같이 백 슬래시로 이스케이프 정규식 반복 문자 ). 이것은$2
규칙의 오른쪽에서 참조 할 수 있습니다
- 첫 번째 대괄호 세트는-
?
앞의 문자가 있으므로이 경우, 선택적 수단 모두/blog/1/foo/
와/blog/1/foo
같은 장소에 다시 것$
이것은 우리가 일치시키고 싶은 문자열의 끝을 나타냅니다
플래그
재 작성 규칙 끝에 특정 조건을 지정하기 위해 대괄호 안에 추가되는 옵션입니다. 다시 말하지만, 문서 에서 읽을 수있는 많은 다른 플래그가 있지만 더 일반적인 플래그 중 일부를 살펴 보겠습니다.
NC
대소 문자 없음 플래그는 다시 쓰기 규칙이 대소 문자를 구분하지 않음을 의미하므로 위의 예제 규칙의 경우 /blog/1/foo/
및 /BLOG/1/foo/
(또는이 변형이 모두) 일치 함을 의미합니다.
L
마지막 플래그는 이것이 처리되어야하는 마지막 규칙임을 나타냅니다. 이는이 규칙이 일치하는 경우에만 현재 다시 쓰기 처리 실행에서 더 이상 규칙이 평가되지 않음을 의미합니다. 규칙이 일치하지 않으면 평소대로 다른 모든 규칙이 시도됩니다. L
플래그를 설정하지 않으면 이후에 다시 작성된 URL에 다음 규칙이 모두 적용됩니다 .
END
Apache 2.4부터 [END]
플래그 를 사용할 수도 있습니다 . 이것과 일치하는 규칙은 추가 별칭 / 다시 쓰기 처리를 완전히 종료합니다. ( [L]
예를 들어 하위 디렉토리에 또는 외부 디렉토리를 다시 쓸 때와 같이 플래그가 종종 두 번째 라운드를 트리거 할 수 있습니다.)
QSA
쿼리 문자열 추가 플래그를 사용하면 추가 변수를 지정된 URL로 전달하여 원래 get 매개 변수에 추가 할 수 있습니다. 이 예에서는 /blog/1/foo/?comments=15
로드가/blog/index.php?id=1&title=foo&comments=15
R
이 플래그는 위 예제에서 사용한 것이 아니지만 언급 할 가치가있는 것으로 생각됩니다. 이를 통해 상태 코드를 포함하는 옵션 (예 :)을 사용하여 http 리디렉션을 지정할 수 있습니다 R=301
. 예를 들어, / myblog /에서 / blog /로 301 리디렉션을 수행하려면 다음과 같은 규칙을 작성하면됩니다.
RewriteRule ^/myblog/(*.)$ /blog/$1 [R=301,QSA,L]
재 작성 조건
다시 쓰기 조건을 사용하면 다시 쓰기가 더욱 강력 해져서보다 구체적인 상황에 대한 다시 쓰기 를 지정할 수 있습니다. documentation 에서 읽을 수있는 조건이 많이 있지만 몇 가지 일반적인 예를 터치하고 설명합니다.
# if the host doesn't start with www. then add it and redirect
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^ http://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
이는 매우 일반적인 관행이며 도메인 www.
이없는 경우 도메인을 앞에 추가 하고 301 리디렉션을 실행합니다. 예를 들어,로드 http://example.com/blog/
하면http://www.example.com/blog/
# if it cant find the image, try find the image on another domain
RewriteCond %{REQUEST_URI} \.(jpg|jpeg|gif|png)$ [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*)$ http://www.example.com/$1 [L]
이는 일반적이지 않지만 파일 이름이 서버에 존재하는 디렉토리 또는 파일 인 경우 실행되지 않는 규칙의 좋은 예입니다.
%{REQUEST_URI} \.(jpg|jpeg|gif|png)$ [NC]
파일 확장자가 jpg, jpeg, gif 또는 png (대소 문자 구분 안 함) 인 파일에 대해서만 다시 쓰기를 실행합니다.%{REQUEST_FILENAME} !-f
파일이 현재 서버에 있는지 확인하고 파일이 없으면 다시 쓰기를 실행합니다%{REQUEST_FILENAME} !-d
파일이 현재 서버에 있는지 확인하고 파일이 없으면 다시 쓰기를 실행합니다- 다시 쓰기는 다른 도메인에 동일한 파일을로드하려고 시도합니다
참고 문헌
스택 오버플로가 많은 시작하는 다른 훌륭한 자원을 :
- Serverfault : mod_rewrite에 대해 알고 싶었던 모든 것
( 사용을^/
위해 패턴 접두사 에서 슬래시를 제거해야.htaccess
합니다.) - 해야 할 것과하지 말아야 할 것은 mod_rewrite의 숨겨진 기능입니다 .
- 가장 인기있는 모드 재 작성 질문과 답변을 살펴보십시오 .
- 아파치 리디렉션 및 리매핑 가이드.
- AskApache Ultimate .htaccess guide
- 그리고 mod-rewrite 태그 위키 참조 .
그리고 새로 온 친절한 정규식 개요 :
- 우리의 정규식 태그 위키 구문 개론합니다.
- 그리고 짧은 아파치 정규식 요약 .
- 다른 regexp.info 기초를 이해하기 쉬운합니다.
자주 사용되는 자리 표시 자
.*
빈 문자열까지도 일치합니다. 이 패턴을 모든 곳에서 사용하고 싶지는 않지만 종종 마지막 대체 규칙에서 사용합니다.[^/]+
경로 세그먼트에 더 자주 사용됩니다. 슬래시 이외의 항목과 일치합니다.\d+
숫자 문자열과 만 일치합니다.\w+
영숫자와 일치합니다. 기본적으로 약어입니다[A-Za-z0-9_]
.[\w\-]+
"슬러그"스타일 경로 세그먼트의 경우 문자, 숫자, 대시-
및_
[\w\-.,]+
마침표와 쉼표를 추가합니다. charclasses\-
에서 이스케이프 된 대시를 선호하십시오[…]
.\.
리터럴 기간을 나타냅니다. 그렇지 않으면.
외부는[…]
모든 기호에 대한 자리 표시 자입니다.
이러한 각 자리 표시자는 일반적 (…)
으로 캡처 그룹 으로 괄호로 묶습니다. 그리고 전체 패턴은 종종 ^………$
시작 + 끝 마커에 있습니다. "패턴"을 인용하는 것은 선택 사항입니다.
규칙을 다시 작성
다음 예제는 PHP 중심이며 조금 더 점증 적이며 유사한 경우에 더 쉽게 적용 할 수 있습니다. 그것들은 요약 일 뿐이며, 종종 더 많은 변형이나 상세한 Q & A에 연결됩니다.
정적 매핑
/contact
,/about
내부 파일 체계로 몇 개의 페이지 이름을 줄이는 것이 가장 간단합니다.
RewriteRule ^contact$ templ/contact.html RewriteRule ^about$ about.php
숫자 식별자
/object/123
http://example.com/article/531
기존 PHP 스크립트 와 같은 바로 가기를 소개 하는 것도 쉽습니다. 숫자 자리 표시자는$_GET
매개 변수 로 다시 매핑 할 수 있습니다 .RewriteRule ^article/(\d+)$ article-show.php?id=$1 # └───────────────────────────┘
슬러그 스타일 플레이스 홀더
/article/with-some-title-slug
/article/title-string
자리 표시자를 허용하도록 해당 규칙을 쉽게 확장 할 수 있습니다 .RewriteRule ^article/([\w-]+)$ article-show.php?title=$1 # └────────────────────────────────┘
참고 스크립트가 있어야 할 수 있습니다 (또는 적용 할 수) 다시 데이터베이스 식별자에 그 제목을 매핑 할 수 있습니다. 규칙만으로는 정보가 허술한 정보를 만들거나 추측 할 수 없습니다.
숫자 접두사가있는 슬러그
/readable/123-plus-title
따라서
/article/529-title-slug
실제로 사용되는 혼합 경로가 종종 표시 됩니다.RewriteRule ^article/(\d+)-([\w-]+)$ article.php?id=$1&title=$2 # └───────────────────────────────┘
title=$2
어쨌든 스크립트는 일반적으로 데이터베이스 ID에 의존하기 때문에 어쨌든 전달을 건너 뛸 수 있습니다 . 는-title-slug
임의의 URL 장식되었다.대체 목록과의 균일 성
/foo/…
/bar/…
/baz/…
여러 가상 페이지 경로에 대해 유사한 규칙이있는 경우
|
다른 목록 과 일치시키고 압축 할 수 있습니다 . 그리고 다시 내부 GET 매개 변수에 다시 할당하십시오.# ┌─────────────────────────┐ RewriteRule ^(blog|post|user)/(\w+)$ disp.php?type=$1&id=$2 # └───────────────────────────────────┘
RewriteRule
너무 복잡해지면 개별으로 나눌 수 있습니다 .관련 URL을 다른 백엔드로 디스패치
/date/SWITCH/backend
대체 목록의보다 실용적인 사용은 요청 경로를 고유 한 스크립트로 맵핑하는 것입니다. 예를 들어 날짜를 기준으로 이전 및 최신 웹 응용 프로그램에 균일 한 URL을 제공하려면
# ┌─────────────────────────────┐ # │ ┌───────────┼───────────────┐ RewriteRule ^blog/(2009|2010|2011)/([\d-]+)/?$ old/blog.php?date=$2 RewriteRule ^blog/(\d+)/([\d-]+)/?$ modern/blog/index.php?start=$2 # └──────────────────────────────────────┘
이것은 2009-2011 게시물을 한 스크립트에 다시 매핑하고 다른 모든 연도는 다른 처리기에 암시 적으로 다시 매핑합니다. 노트 보다 구체적인 규칙이 먼저오고 . 각 스크립트는 다른 GET 매개 변수를 사용할 수 있습니다.
/
경로 슬래시 이외의 다른 구분 기호
/user-123-name
가상 디렉토리 구조를 시뮬레이션하기 위해 가장 일반적으로 RewriteRules가 표시됩니다. 그러나 창의력을 발휘하지 않아도됩니다.
-
분할 또는 구조에 하이픈을 사용할 수도 있습니다 .RewriteRule ^user-(\d+)$ show.php?what=user&id=$1 # └──────────────────────────────┘ # This could use `(\w+)` alternatively for user names instead of ids.
또한 일반적인
/wiki:section:Page_Name
구성표 :RewriteRule ^wiki:(\w+):(\w+)$ wiki.php?sect=$1&page=$2 # └─────┼────────────────────┘ │ # └────────────────────────────┘
때때로 그것은 사이의 대체에 적합
/
-delimiters 및:
또는.
심지어 같은 규칙이있다. 또는 변형을 다른 스크립트에 매핑하려면 두 개의 RewriteRules를 다시 사용하십시오.선택적 후행
/
슬래시
/dir
=/dir/
디렉토리 스타일 경로를 선택할 때 최종 경로 유무에 관계없이 경로에 도달 할 수 있습니다 /
RewriteRule ^blog/([\w-]+)/?$ blog/show.php?id=$1 # ┗┛
이제이 손잡이 모두
http://example.com/blog/123
와/blog/123/
. 이/?$
방법은 다른 RewriteRule에 쉽게 추가 할 수 있습니다.가상 경로를위한 유연한 세그먼트
.*/.*/.*/.*
발생하는 대부분의 규칙은 제한된
/…/
리소스 경로 세그먼트 세트 를 개별 GET 매개 변수에 맵핑합니다 . 그러나 일부 스크립트 는 다양한 옵션을 처리합니다 . Apache regexp 엔진은 임의의 수의 옵션을 선택적으로 허용하지 않습니다. 그러나 쉽게 규칙 블록으로 쉽게 확장 할 수 있습니다.Rewriterule ^(\w+)/?$ in.php?a=$1 Rewriterule ^(\w+)/(\w+)/?$ in.php?a=$1&b=$2 Rewriterule ^(\w+)/(\w+)/(\w+)/?$ in.php?a=$1&b=$2&c=$3 # └─────┴─────┴───────────────────┴────┴────┘
최대 5 개의 경로 세그먼트가 필요한 경우이 체계를 5 개의 규칙으로 복사하십시오. 물론보다 구체적인
[^/]+
자리 표시자를 각각 사용할 수 있습니다 . 여기서 순서는 겹치지 않기 때문에 중요하지 않습니다. 따라서 가장 자주 사용되는 경로를 먼저 갖는 것이 좋습니다.또는
?p[]=$1&p[]=$2&p[]=3
스크립트가 단순히 사전 분할을 선호하는 경우 쿼리 문자열을 통해 PHP 배열 매개 변수를 활용할 수 있습니다 . (포괄적 인 규칙 만 사용하고 스크립트 자체가 REQUEST_URI에서 세그먼트를 확장하도록하는 것이 더 일반적이지만)선택적 세그먼트
prefix/opt?/.*
일반적인 변형은 규칙 내에 선택적 접두사 를 사용 하는 것입니다. 정적 문자열이나 더 제한된 자리 표시자가있는 경우 일반적으로 의미가 있습니다.
RewriteRule ^(\w+)(?:/([^/]+))?/(\w+)$ ?main=$1&opt=$2&suffix=$3
이제 더 복잡한 패턴은
(?:/([^/])+)?
단순히 캡처하지 않는(?:…)
그룹을 감싸고 선택 사항으로 만듭니다)?
. 포함 된 자리 표시자는 replacement([^/]+)
pattern$2
이지만 중간/…/
경로 가 없으면 비어 있습니다 .나머지를 캡처
/prefix/123-capture/…/*/…whatever…
앞에서 말했듯이 너무 일반적인 재 작성 패턴은 원하지 않습니다. 그러나 정적 및 특정 비교를
.*
때때로 결합하는 것이 합리적 입니다.RewriteRule ^(specific)/prefix/(\d+)(/.*)?$ speci.php?id=$2&otherparams=$2
이것은
/…/…/…
후행 경로 세그먼트를 옵션 화했습니다 . 물론,이를 처리하기 위해 처리 스크립트가 필요하며 추출 된 매개 변수 자체를 variabl-ify ( 웹- "MVC" 프레임 워크가하는 것)가 필요합니다.후행 파일 "확장명"
/old/path.HTML
URL에는 실제로 파일 확장자가 없습니다. 이 전체 참조 내용은 다음과 같습니다 (= URL은 가상 로케이터이며 반드시 직접 파일 시스템 이미지는 아님). 그러나 이전에 1 : 1 파일 매핑이 있었다면 더 간단한 규칙을 만들 수 있습니다 .
RewriteRule ^styles/([\w\.\-]+)\.css$ sass-cache.php?old_fn_base=$1 RewriteRule ^images/([\w\.\-]+)\.gif$ png-converter.php?load_from=$2
다른 일반적인 용도는
.html
최신.php
처리기로 경로를 다시 매핑 하거나 개별 (실제 / 실제) 파일에 대해서만 디렉토리 이름 별칭을 지정하는 것입니다.탁구 (직접 리디렉션 및 재 작성)
/ugly.html
← →/pretty
따라서 어느 시점에서 deceze 로 요약 된 것처럼 예쁜 링크 만 전달하도록 HTML 페이지를 다시 작성합니다 . 그 동안 여전히 책갈피 에서조차 이전 경로에 대한 요청을받습니다 . 으로 해결 , 당신은 / 화면에 브라우저를 탁구 - 핑 새로운 URL을 설정할 수 있습니다.
이 일반적인 속임수는 들어오는 URL이 더 이상 사용되지 않거나 못생긴 이름 지정 체계를 따를 때마다 30x / 위치 리디렉션을 보내는 것 입니다. 브라우저 것이다 다음 rerequest 나중에 원본 또는 새 위치 (단지 내부적으로) 다시 작성하는 새 / 꽤 URL.
# redirect browser for old/ugly incoming paths RewriteRule ^old/teams\.html$ /teams [R=301,QSA,END] # internally remap already-pretty incoming request RewriteRule ^teams$ teams.php [QSA,END]
이 예제 가 안전하게 대체 하는
[END]
대신 사용하는 방법에 유의하십시오[L]
. 이전 Apache 2.2 버전의 경우 쿼리 문자열 매개 변수를 다시 매핑하는 것 외에도 다른 해결 방법을 사용할 수 있습니다. 예를 들어 ugly를 예쁜 URL로 리디렉션하고 무한 루프없이 ugly 경로로 다시 매핑하십시오.␣패턴의 공백
/this+that+
그것은 아니다 꽤 브라우저의 주소 표시 줄에,하지만 당신은 URL에 공백을 사용할 수 있습니다. 다시 쓰기 패턴의 경우 백 슬래시 이스케이프
\␣
공백을 사용 하십시오. 그렇지 않으면"
전체 패턴 또는 대체를 인용하십시오.RewriteRule "^this [\w ]+/(.*)$" "index.php?id=$1" [L]
클라이언트 는 공백 이
+
있거나%20
공백으로 URL을 직렬화합니다 . 그러나 RewriteRules에서는 모든 상대 경로 세그먼트에 대한 리터럴 문자로 해석됩니다.
자주 복제 :
캐치 - 모두를위한 중앙 디스패처 / 프론트 컨트롤러 스크립트
RewriteCond %{REQUEST_URI} !-f RewriteCond %{REQUEST_URI} !-d RewriteRule ^.*$ index.php [L]
PHP 프레임 워크 또는 WebCMS / 포털 스크립트에서 자주 사용됩니다. 그런 다음 실제 경로 분할은 PHP를 사용하여 처리됩니다
$_SERVER["REQUEST_URI"]
. 개념적으로 그것은 "mod_rewrite 당"URL 처리와 거의 반대입니다. (FallBackResource
대신 사용하십시오.)www.
호스트 이름에서 제거이것은 쿼리 문자열을 복사하지 않습니다.
# ┌──────────┐ RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC] │ RewriteRule ^(.*)$ http://%1/$1 [R=301,L] │ # ↓ └───┼────────────┘ # └───────────────┘
참조 :
· .htaccess의 다른 프로토콜에 대한 URL 재 작성
· 일반 htaccess를 www가 아닌 www로 리디렉션
· .htaccess- "www"강제 실행 방법 일반적인 방법으로?RewriteCond / RewriteRule 콤보는 다음과 같은 경우에도 일치하는 (
%1
및$1
)가 양방향으로 상호 작용 하여 더 복잡 할 수 있습니다 .
아파치 매뉴얼-mod_rewrite intro , Copyright 2015 The Apache Software Foundation, AL-2.0로 리디렉션
HTTPS://
RewriteCond %{SERVER_PORT} 80 RewriteRule ^(.*)$ https://example.com/$1 [R,L]
PHP 확장 "제거"
RewriteCond %{REQUEST_FILENAME}.php -f RewriteRule ^(.+)$ $1.php [L] # or [END]
오래된 .html 경로를 .php 스크립트로 별칭 지정
참조 : http://httpd.apache.org/docs/2.4/rewrite/remapping.html#backward-compatibility
"/ page"와 같은 URL에서 "/index.php/page"와 같은 스크립트로 다시 작성
하위 도메인을 폴더로 리디렉션
일반적인 .htaccess
함정
이제 소금 한알로 이것을 가져 가십시오. 모든 조언을 모든 상황에 대해 일반화 할 수있는 것은 아닙니다. 이것은 잘 알려진 몇 가지 명백한 걸림돌에 대한 간단한 요약입니다.
사용
mod_rewrite
및.htaccess
디렉토리 별 구성 파일에서 실제로 RewriteRules를 사용하려면 다음을 수행해야합니다.
서버가
AllowOverride All
활성화 되어 있는지 확인하십시오 . 그렇지 않으면 디렉토리 별.htaccess
지시문이 무시되고 RewriteRules가 작동하지 않습니다.분명히 했습니다
mod_rewrite
활성화 당신의httpd.conf
모듈 섹션.각 규칙 목록 앞에
RewriteEngine On
스틸을 붙 입니다. mod_rewrite가 암시 적으로 활성화되어<VirtualHost>
있고<Directory>
섹션에서는 디렉토리 별.htaccess
파일을 개별적으로 소환해야합니다.
슬래시
^/
가 일치하지 않습니다일반적으로
.htaccess
RewriteRule 패턴을 시작하지 않아야^/
합니다.RewriteRule ^/article/\d+$ … ↑
이것은 종종 오래된 튜토리얼에서 볼 수 있습니다. 그리고 그것은 고대 아파치 1.x 버전에 맞았습니다. 요즘 요청 경로는 RewriteRules 에서 편리 하게 디렉토리에 상대적 입니다
.htaccess
. 그냥 앞/
을 내버려 두십시오 .· 슬래시는 여전히
<VirtualHost>
섹션 에서 정확 합니다. 그렇기 때문에^/?
규칙 패리티에 대해 선택적으로 선택되는 경우가 종종 있습니다 .
· 또는를 사용할 때도RewriteCond %{REQUEST_URI}
선두와 일치합니다/
.
· Webmaster.SE : mod_rewrite 패턴에서 선행 슬래시 (/)는 언제 필요합니까?를 참조하십시오.<IfModule *>
래퍼가 시작되었습니다!많은 예에서 이것을 보았을 것입니다.
<IfModule mod_rewrite.c> Rewrite… </IfModule>
- 그것은 수행 에서 메이크업 감각
<VirtualHost>
섹션 -이 같은 ScriptAliasMatch 같은 다른 대체 옵션과 결합 된 경우. (그러나 아무도 그렇게하지 않습니다). - 또한
.htaccess
오픈 소스 프로젝트가 많은 기본 규칙 세트에 일반적으로 배포됩니다 . 그것은 단지 폴백 (fallback)과 같은 의미이며 "추악한"URL을 기본값으로 유지합니다.
그러나 일반적으로 자신의 파일 에는 원하지 않습니다
.htaccess
.- 첫째, mod_rewrite는 임의로 분리되지 않습니다. (그렇다면 더 큰 문제가 생길 것입니다).
- 실제로 비활성화되어 있으면 RewriteRules가 여전히 작동하지 않습니다.
- HTTP
500
오류 를 방지하기위한 것 입니다. 일반적으로 달성하는 것은 HTTP404
오류로 사용자를 매기는 것입니다. ( 생각하면 훨씬 사용자 친화적이지 않습니다.) - 실제로 더 유용한 로그 항목 또는 서버 알림 메일을 억제합니다. 당신은 없을 거라고 아무도 현명를 당신의 RewriteRules가 작동하지 않을 이유에.
일반화 된 보호 수단으로 유혹되는 것들은 종종 실제로 장애물로 밝혀졌습니다.
- 그것은 수행 에서 메이크업 감각
RewriteBase
필요 하지 않으면 사용 하지 마십시오많은 복사 + 붙여 넣기 예에는
RewriteBase /
지시문이 포함되어 있습니다 . 어쨌든 암시 적 기본값이됩니다. 따라서 실제로는 필요하지 않습니다. 멋진 VirtualHost 다시 쓰기 체계에 대한 해결 방법이며 일부 공유 호스팅 업체의 DOCUMENT_ROOT 경로를 잘못 추측했습니다.더 깊은 하위 디렉토리의 개별 웹 응용 프로그램과 함께 사용하는 것이 좋습니다. 이러한 경우 RewriteRule 패턴을 단축 할 수 있습니다. 일반적으로 디렉토리 별 규칙 세트에서 상대 경로 지정자를 선호하는 것이 가장 좋습니다.
.htaccess에서 RewriteBase의 작동 방식을 참조하십시오.
MultiViews
가상 경로가 겹치면 비활성화URL 재 작성은 주로 가상 수신 경로 를 지원하는 데 사용됩니다 . 일반적으로 당신은 단지 하나의 디스패처 스크립트 (가
index.php
) 또는 몇 개인 핸들러 (articles.php
,blog.php
,wiki.php
, ...). 후자 는 유사한 가상 RewriteRule 경로와 충돌 할 수 있습니다 ./article/123
예를 들어 요청article.php
은/123
PATH_INFO로 암시 적으로 맵핑 될 수 있습니다 . commonplaceRewriteCond
!-f
+로 규칙을 지키고!-d
PATH_INFO 지원을 비활성화하거나 disable으로 설정해야Options -MultiViews
합니다.어떤 당신이 항상 말을하지 해야합니다 . 컨텐츠 협상은 가상 자원에 대한 자동화입니다.
주문이 중요하다
mod_rewrite에 대해 알고 싶은 모든 것을 참조하십시오 . 여러 RewriteRules를 결합하면 종종 상호 작용이 발생합니다. 이것은
[L]
플래그 당 습관적으로 방지 할 수있는 것이 아니라 한 번 정복 한 계획입니다. 가상 경로가 실제 대상 핸들러에 도달 할 때까지 한 규칙에서 다른 규칙으로 가상 경로를 다시 다시 작성할 수 있습니다 .그럼에도 불구하고 당신은 것입니다 종종 가장 구체적인 규칙 (고정 문자열이 원하는
/forum/…
패턴, 또는 더 제한적인 자리[^/.]+
에서) 초기 규칙을. 일반적인 말 괄호 규칙 (.*
)이 나중 규칙 에 더 잘 남습니다 . (예외는RewriteCond -f/-d
기본 블록으로서의 보호입니다.)스타일 시트 및 이미지 작동이 중지됩니다
가상 디렉터리 구조를 도입하면
/blog/article/123
HTML의 상대 리소스 참조 (예 :)에 영향을줍니다<img src=mouse.png>
. 다음으로 해결할 수 있습니다.- 서버 절대 참조 만 사용
href="/old.html"
하거나src="/logo.png"
- 종종
<base href="/index">
HTML<head>
섹션 에 추가하면 됩니다 . 이것은 이전에 있었던 것에 대한 상대적 참조를 암시 적으로 리 바인드합니다.
다른 RewriteRules 를 만들어 원래 위치 로 리 바인드
.css
하거나.png
경로를 지정할 수도 있습니다. 그러나 그것은 불필요하거나 여분의 리디렉션이 발생하고 캐싱을 방해합니다.- 서버 절대 참조 만 사용
RewriteConds는 하나의 RewriteRule 만 마스크합니다.
일반적인 오해는 RewriteCond가 여러 RewriteRules를 시각적으로 정렬하여 차단한다는 것입니다.
RewriteCond %{SERVER_NAME} localhost RewriteRule ^secret admin/tools.php RewriteRule ^hidden sqladmin.cgi
기본값이 아닌 당신은 할 수 있습니다 그들을 체인 은 Using
[S=2]
플래그. 그렇지 않으면 반복해야합니다. 재 작성 처리를 일찍 [END] 수행하기 위해 "반전 된"기본 규칙을 만들 수도 있습니다.QUERY_STRING이 RewriteRules에서 면제
RewriteRule index.php\?x=y
mod_rewrite는 기본값 당 상대 경로와 비교하기 때문에을 일치시킬 수 없습니다 . 그러나 다음을 통해 별도로 일치시킬 수 있습니다.RewriteCond %{QUERY_STRING} \b(?:param)=([^&]+)(?:&|$) RewriteRule ^add/(.+)$ add/%1/$1 # ←──﹪₁──┘
.htaccess
vs.<VirtualHost>
디렉토리 별 구성 파일에서 RewriteRules를 사용하는 경우 정규 표현식 성능에 대한 걱정은 의미가 없습니다. Apache는 공통 라우팅 프레임 워크를 사용하여 PHP 프로세스보다 더 긴 컴파일 된 PCRE 패턴을 유지합니다. 트래픽이 많은 사이트의 경우 규칙 테스트가 완료되면 규칙 세트를 가상 호스트 서버 구성으로 이동하는 것을 고려해야합니다.
이 경우 선택적
^/?
디렉토리 구분 기호 접두사를 선호하십시오 . 이를 통해 PerDir과 서버 구성 파일간에 RewriteRules를 자유롭게 이동할 수 있습니다.무언가 가 작동하지 않을 때마다
걱정하지 마십시오.
비교
access.log
및error.log
종종 RewriteRule이
error.log
and 및 을보고 오작동하는 방식을 파악할 수 있습니다access.log
. 액세스 시간을 연관시켜 원래 요청 경로와 Apache가 해석 할 수없는 경로 / 파일을 확인하십시오 (오류 404/500).이것은 어느 RewriteRule이 범인인지는 알려주지 않습니다. 그러나 접근하기 어려운 최종 경로
/docroot/21-.itle?index.php
는 추가 검사 장소를 제공 할 수 있습니다. 그렇지 않으면 예측 가능한 경로를 얻을 때까지 규칙을 비활성화하십시오.RewriteLog 활성화
Apache RewriteLog 문서를 참조하십시오 . 디버깅을 위해 vhost 섹션에서이를 활성화 할 수 있습니다.
# Apache 2.2 RewriteLogLevel 5 RewriteLog /tmp/rewrite.log # Apache 2.4 LogLevel alert rewrite:trace5 #ErrorLog /tmp/rewrite.log
그러면 각 요청에 따라 들어오는 요청 경로가 어떻게 수정되는지에 대한 자세한 요약이 제공됩니다.
[..] applying pattern '^test_.*$' to uri 'index.php' [..] strip per-dir prefix: /srv/www/vhosts/hc-profi/index.php -> index.php [..] applying pattern '^index\.php$' to uri 'index.php'
지나치게 일반적인 규칙과 정규식 사고를 좁히는 데 도움이됩니다.
참조 :
· .htaccess가 작동하지 않음 (mod_rewrite)
· .htaccess 재 작성 규칙 디버깅 팁자신의 질문을하기 전에
아시다시피, 스택 오버플로는 mod_rewrite에 대한 질문을하는 데 매우 적합합니다. 이를 확인 에 주제 , 이전의 연구와 시도 (회피 중복 응답)을 포함하여 기본 보여 정규식 이해를하고 :
- 입력 URL, 잘못 작성된 대상 경로, 실제 디렉토리 구조의 전체 예제를 포함하십시오 .
- 전체 RewriteRule의 세트, 그러나 또한 추정 결함이 밖으로 하나.
$_SERVER
매개 변수가 일치하지 않는 경우 Apache 및 PHP 버전, OS 유형, 파일 시스템, DOCUMENT_ROOT 및 PHP 환경.- 귀하의 발췌
access.log
및error.log
기존 규칙으로 해결 된 사항을 확인합니다. 더 나은 아직rewrite.log
요약.
이를 통해보다 빠르고 정확한 답변을 얻을 수 있으며 다른 사람들에게 더 유용합니다.
당신의 코멘트
.htaccess
어딘가에서 예제를 복사하는 경우을 포함하도록주의하십시오
# comment and origin link
. 속성을 생략하는 것은 나쁜 방법 일 뿐이지 만 나중에 유지 관리에 심각한 영향을줍니다. 모든 코드 또는 튜토리얼 소스를 문서화하십시오. 특히, 미지의 동안에는 마법의 블랙 박스처럼 취급하지 않는 것에 더 관심을 가져야합니다."SEO"가 아닙니다. URL
면책 조항 : 단지 애완 동물 친구. 당신은 종종 "SEO"링크 또는 무언가로 불리는 꽤 URL 재 작성 체계를 듣습니다. 이것은 인터넷 검색 예제에 유용하지만 날짜가 지난 잘못된 이름입니다.
현대적인 검색 엔진의 아무도는 정말 방해하지 않습니다
.html
및.php
패스 세그먼트 (segment), 또는에서?id=123
그 문제에 대한 쿼리 문자열. AltaVista와 같은 오래된 검색 엔진은 잠재적으로 모호한 액세스 경로를 가진 웹 사이트를 크롤링 하지 않았습니다 . 최신 크롤러는 종종 깊은 웹 리소스를 원합니다.개념적으로 "예쁜"URL을 사용해야하는 것은 웹 사이트를 사용자에게 친숙 하게 만드는 것 입니다.
- 읽기 쉽고 명백한 리소스 체계가 있습니다.
- URL의 수명이 길다 (AKA permalinks ).
- 를 통해 검색 가능성 제공
/common/tree/nesting
.
그러나 적합성에 대한 고유 한 요구 사항을 희생하지 마십시오.
도구
대부분의 GET 매개 변수 URL에 대해 RewriteRules를 생성하는 다양한 온라인 도구가 있습니다.
- http://www.generateit.net/mod-rewrite/index.php
- http://www.ipdistance.com/mod_rewrite.php
- http://webtools.live2support.com/misc_rewrite.php
대부분 [^/]+
일반 자리 표시자를 출력 하지만 사소한 사이트에는 충분합니다.
mod_rewrite의 대안
RewriteRules를 사용하지 않고도 많은 기본 가상 URL 체계를 달성 할 수 있습니다. 아파치는 PHP 스크립트를 .php
확장 없이 , 그리고 가상의 PATH_INFO
인수 로 호출 할 수있게 한다.
사용 PATH_INFO , 루크
요즘
AcceptPathInfo On
은 종종 기본적으로 활성화되어 있습니다. 기본적으로.php
다른 리소스 URL이 가상 인수를 수행하도록 허용 합니다.http://example.com/script.php/virtual/path
이제 이것은 추가 인수를 원하는
/virtual/path
대로$_SERVER["PATH_INFO"]
처리 할 수있는 곳 으로 PHP에 표시됩니다 .이것에 아파치 별도의 입력 경로 세그먼트를 구비 한 편리하지
$1
,$2
,$3
별개로 전달$_GET
PHP하는 변수. 적은 노력으로 "예쁜 URL"을 모방 할뿐입니다.확장 을 숨기려면 MultiViews 활성화
.php
.php
URL에서 "파일 확장자"를 피하는 가장 간단한 옵션 은 다음과 같습니다.Options +MultiViews
일치하는 기본 이름으로 인해 Apache에서
article.php
HTTP 요청을 선택 합니다/article
. 그리고 이것은 위에서 언급 한 PATH_INFO 기능과 함께 잘 작동합니다. 그래서 당신은 같은 URL을 사용할 수 있습니다http://example.com/article/virtual/title
. 여러 PHP 호출 지점 / 스크립트가있는 전통적인 웹 응용 프로그램이있는 경우 의미가 있습니다.MultiViews는 다른 / 광범위한 목적을 가지고 있습니다. 그것은 초래 아주 작은 아파치가 항상 일치하는 basename이 다른 파일을 찾습니다 있기 때문에, 성능 저하. 그것은 실제로 의미있어 내용 협상 브라우저 (예 : 가용 자원 중 가장 좋은 대안을받을 수 있도록,
article.en.php
,article.fr.php
,article.jp.mp4
).확장없는
.php
스크립트를 위한 SetType 또는 SetHandler.php
URL에서 접미사 를 피하는보다 직접적인 접근 방식 은 다른 파일 체계에 맞게 PHP 처리기 를 구성하는 것 입니다. 가장 간단한 옵션은.htaccess
다음을 통해 기본 MIME / 핸들러 유형을 재정의하는 것입니다 .DefaultType application/x-httpd-php
이렇게하면
article.php
스크립트 이름 을article
(확장자없이) 그냥 바꿀 수 있지만 여전히 PHP 스크립트로 처리 할 수 있습니다.이제 모든 확장 파일이 PHP를 통해 파이프되기 때문에 보안 및 성능에 영향을 줄 수 있습니다. 따라서 개별 파일에 대해서만이 동작을 설정할 수 있습니다.
<Files article> SetHandler application/x-httpd-php # or SetType </Files>
이것은 서버 설정과 사용 된 PHP SAPI에 따라 다소 다릅니다. 일반적인 대안은
ForceType application/x-httpd-php
또는AddHandler php5-script
입니다.이러한 설정은 하나
.htaccess
에서 하위 폴더로 전파됩니다 . 당신은 항상 스크립트 실행 (사용하지 않아야SetHandler None
하고Options -Exec
또는php_flag engine off
정적 자원 등), 업로드 / 디렉토리 등다른 Apache 재 작성 체계
많은 옵션 중에서 Apache는 RewriteRules
mod_alias
와 마찬가지로 작동하는 기능을 제공 합니다mod_rewrite
. 그러나 대부분은<VirtualHost>
디렉토리 별.htaccess
구성 파일이 아닌 섹션 에서 설정해야 합니다.ScriptAliasMatch
주로 CGI 스크립트 용이지만 PHP에서도 작동합니다. 그것은 어떤 식 으로든 정규 표현식을 허용합니다RewriteRule
. 실제로 모든 전면 컨트롤러를 구성하는 것이 가장 강력한 옵션 일 것입니다.그리고 평범한
Alias
몇 가지 간단한 다시 쓰기 체계도 도움이됩니다.ErrorDocument
PHP 스크립트가 가상 경로를 처리하도록 일반 지시문도 사용할 수 있습니다. 그러나 이것은 해결하기 어려운 해결책이지만 GET 요청 이외의 것은 금지하고 error.log를 정의에 따라 넘칩니다.
추가 팁 은 http://httpd.apache.org/docs/2.2/urlmapping.html 을 참조 하십시오 .
'Programming' 카테고리의 다른 글
Javadoc의 좋은 예 (0) | 2020.06.23 |
---|---|
CSS 선택기에서 요소 ID의 콜론 처리 (0) | 2020.06.23 |
인터페이스의 생성자? (0) | 2020.06.23 |
SQL Server 테이블의 변경 사항을 확인 하시겠습니까? (0) | 2020.06.23 |
형제 패키지 가져 오기 (0) | 2020.06.23 |