Apache mod_rewrite
당신이 찾고있는 것은 mod_rewrite입니다 .
설명 : 요청 된 URL을 즉시 재 작성할 수있는 규칙 기반 재 작성 엔진을 제공합니다.
일반적으로 mod_rewrite
요청 된 문서를 지정된 정규식과 일치시켜 작업 한 다음 내부적으로 (아파치 프로세스 내에서) 또는 외부 적으로 (클라이언트 브라우저에서) URL 재 작성을 수행합니다. 이러한 재 작성은 내부적으로 example.com/foo를 example.com/foo/bar에 대한 요청으로 번역하는 것처럼 간단 할 수 있습니다.
Apache 문서에는 mod_rewrite
가이드가 포함되어 있으며 원하는 작업 중 일부가 여기에 포함되어 있다고 생각합니다. 자세한 mod_rewrite 가이드 .
www
하위 도메인 강제
모든 URL 앞에 "www"를 강제하고 싶습니다. domain.com이 아니라 www.domain.com/page입니다.
재 작성 안내서에는 Canonical Hostname 예제에 대한 지침이 포함되어 있습니다.
후행 슬래시 제거 (1 부)
페이지에서 모든 후행 슬래시를 제거하고 싶습니다.
재 작성 가이드에는 정반대에 대한 예가 포함되어 있습니다 . 즉, 항상 후행 슬래시를 포함하므로 왜 이렇게해야하는지 잘 모르겠습니다 . 문서는 후행 슬래시를 제거하면 문제를 일으킬 가능성이 크다고 제안합니다.
후행 슬래시 문제
기술:
모든 웹 마스터는 디렉토리를 참조하는 URL에서 후행 슬래시 문제에 대한 노래를 부를 수 있습니다. 누락 된 경우 서버는 오류를 덤프합니다. /~quux/foo
대신 말하면 /~quux/foo/
서버가 foo라는 파일을 검색하기 때문입니다. 그리고이 파일은 디렉토리이기 때문에 불평합니다. 실제로 대부분의 경우 자체적으로 수정하려고 시도하지만 때로는이 메커니즘을 사용자가 에뮬레이션해야합니다. 예를 들어 CGI 스크립트 등에 복잡한 URL 재 작성을 많이 한 후에
왜 항상 후행 슬래시를 제거하고 싶은지 확장 할 수 있습니까?
.php
확장 제거
.php를 제거하는 데 필요합니다.
내가 생각할 수있는 가장 가까운 일은 모든 요청 문서를 내부적으로 .php 확장자로 다시 작성하는 것입니다. 즉, example.com/somepage는 대신 example.com/somepage.php에 대한 요청으로 처리됩니다. 이 방식으로 진행하려면 각 페이지가 실제로 파일 시스템에 somepage.php로 존재해야합니다.
정규 표현식의 올바른 조합으로 어느 정도 가능할 것입니다. 그러나 색인 페이지가 올바르게 요청되지 않고 디렉토리와 올바르게 일치하지 않는 몇 가지 가능한 문제를 예견 할 수 있습니다.
예를 들어, example.com/test.php에 대한 요청으로 example.com/test를 올바르게 다시 작성합니다.
RewriteEngine on
RewriteRule ^(.*)$ $1.php
그러나 example.com/.php가 없기 때문에 example.com이로드되지 않습니다.
후행 슬래시를 모두 제거하면 상위 디렉토리의 파일 이름 요청에서 디렉토리 색인 요청을 선택하는 것이 거의 불가능할 것이라고 추측 할 것입니다. 'foobar'디렉토리에 대한 요청을 어떻게 결정합니까?
example.com/foobar
foobar (실제로는 foobar.php)라는 파일에 대한 요청에서
example.com/foobar
RewriteBase
지시문 을 사용하면 가능할 수 있습니다 . 그러나 그렇게하면 RewriteCond
요청이 디렉토리 나 파일에 매핑되는지 파일 시스템 수준 검사를 수행 하기 위해 지시문이 필요 하므로이 문제는 훨씬 더 복잡해집니다 .
즉, 모든 후행 슬래시를 제거해야한다는 요구 사항을 제거하고 대신 후행 슬래시를 강제 추가하면 ".php 확장자 없음"문제가 좀 더 합리적입니다.
# Turn on the rewrite engine
RewriteEngine on
# If the request doesn't end in .php (Case insensitive) continue processing rules
RewriteCond %{REQUEST_URI} !\.php$ [NC]
# If the request doesn't end in a slash continue processing the rules
RewriteCond %{REQUEST_URI} [^/]$
# Rewrite the request with a .php extension. L means this is the 'Last' rule
RewriteRule ^(.*)$ $1.php [L]
이것은 여전히 완벽하지 않습니다 . 파일에 대한 모든 요청에는 여전히 내부적으로 요청에 .php가 추가되어 있습니다. 'hi.txt'를 요청하면 오류 로그에 다음과 같이 기록됩니다.
[Tue Oct 26 18:12:52 2010] [error] [client 71.61.190.56] script '/var/www/test.peopleareducks.com/rewrite/hi.txt.php' not found or unable to stat
그러나 다른 옵션 이 있습니다. 다음과 같이 DefaultType
및 DirectoryIndex
지시문을 설정하십시오 .
DefaultType application/x-httpd-php
DirectoryIndex index.php index.html
2013-11-14 업데이트-nicorellius의 관찰을 통합하도록 위의 스 니펫을 수정했습니다.
이제 hi.txt (및 기타)에 대한 요청이 성공하고 example.com/test에 대한 요청이 처리 된 test.php 버전을 반환하며 index.php 파일이 다시 작동합니다.
이 솔루션에 대한 크레딧을 제공해야합니다. Google에서 php no extension apache 를 검색 하여 Michael J. Radwins 블로그 를 찾았습니다 .
후행 슬래시 제거
일부 검색은 apache remove trailing slashes
일부 검색 엔진 최적화 페이지 를 가져 왔습니다. 분명히 일부 콘텐츠 관리 시스템 (이 경우 Drupal)은 URls에서 후행 슬래시를 사용하거나 사용하지 않고 콘텐츠를 사용할 수있게하여 SEO 세계에서 사이트에 중복 콘텐츠 패널티를 부과합니다. 출처
해결책은 mod_rewrite
요청 된 리소스가 a로 끝나는 조건에서 /
다시 작성하고 301 Permanent Redirect
HTTP 헤더를 다시 전송하여 URL을 다시 작성하는 것을 사용하여 매우 사소한 것처럼 보입니다 .
다음은 도메인이 blamcast.net이라고 가정하고 요청에 선택적으로 접두사가 붙도록 허용하는 그의 예입니다 www.
.
#get rid of trailing slashes
RewriteCond %{HTTP_HOST} ^(www.)?blamcast\.net$ [NC]
RewriteRule ^(.+)/$ http://%{HTTP_HOST}/$1 [R=301,L]
이제 우리는 어딘가에 있습니다. 모두 모아서 어떻게 생겼는지 봅시다.
필수 www.
, no .php
및 후행 슬래시 없음
이것은 도메인이 foobar.com이고 표준 포트 80에서 실행 중이라고 가정합니다.
# Process all files as PHP by default
DefaultType application/x-httpd-php
# Fix sub-directory requests by allowing 'index' as a DirectoryIndex value
DirectoryIndex index index.html
# Force the domain to load with the www subdomain prefix
# If the request doesn't start with www...
RewriteCond %{HTTP_HOST} !^www\.foobar\.com [NC]
# And the site name isn't empty
RewriteCond %{HTTP_HOST} !^$
# Finally rewrite the request: end of rules, don't escape the output, and force a 301 redirect
RewriteRule ^/?(.*) http://www.foobar.com/$1 [L,R,NE]
#get rid of trailing slashes
RewriteCond %{HTTP_HOST} ^(www.)?foobar\.com$ [NC]
RewriteRule ^(.+)/$ http://%{HTTP_HOST}/$1 [R=301,L]
'R'플래그는 RewriteRule
지시문 섹션에 설명되어 있습니다. 단편:
redirect|R [=code]
(강제 리디렉션) http://thishost[:thisport]/
외부 리디렉션을 강제하기 위해 (새 URL을 URI로 만드는 ) 접두사 대체
. 코드가 제공되지 않으면 302 ( MOVED TEMPORARILY ) 의 HTTP 응답 이 반환됩니다.
최종 참고
슬래시 제거를 성공적으로 수행 할 수 없었습니다. 리디렉션으로 인해 무한 리디렉션 루프가 발생했습니다. 원래 솔루션을 자세히 읽은 후 Drupal 설치가 구성되어 있기 때문에 위의 예제가 작동한다는 인상을 받았습니다. 그는 구체적으로 다음과 같이 언급합니다.
일반 Drupal 사이트에서 깨끗한 URL이 활성화 된 상태에서이 두 주소는 기본적으로 상호 교환이 가능합니다.
슬래시가 있거나없는 URL을 참조합니다. 더욱이,
Drupal은라는 파일을 사용 .htaccess
하여 웹 서버에 URL을 처리하는 방법을 알려줍니다. 이것은 Drupal의 깨끗한 URL 마법을 가능하게하는 동일한 파일입니다. .htaccess
파일 시작 부분에 간단한 리디렉션 명령을 추가
하면 서버가 후행 슬래시를 자동으로 제거하도록 강제 할 수 있습니다.