Programming

참조 : mod_rewrite, URL 재 작성 및 "pretty 링크"설명

procodes 2020. 6. 23. 08:06
반응형

참조 : 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

이것은 다시 무엇이든 일치시키고 urlquery 매개 변수 에 원래 요청 된 URL을 추가하여 index.php 파일에 다시 씁니다 . 즉, 들어오는 모든 요청에 ​​대해 index.php 파일이 실행 되고이 파일은의 원래 요청에 액세스 $_GET['url']할 수 있으므로 원하는 모든 작업을 수행 할 수 있습니다.

기본적으로 이러한 다시 쓰기 규칙을 웹 서버 구성 파일에 넣습니다 . 또한 아파치는 .htaccess문서 루트 (예 : .php 파일 옆) 에있는 파일에 파일을 넣을 수 있도록합니다 * .

* 기본 Apache 구성 파일에서 허용하는 경우 선택 사항이지만 종종 사용됩니다.

mod_rewrite가하지 않는

mod_rewrite가 모든 URL을 마술처럼 아름답게 만들지는 않습니다. 이것은 일반적인 오해입니다. 웹 사이트에이 링크가있는 경우 :

<a href="/my/ugly/link.php?is=not&amp;very=pretty">

mod_rewrite가 그것을 예쁘게 만들기 위해 할 수있는 일은 없습니다. 이 링크를 예쁘게 만들려면 다음을 수행해야합니다.

  1. 링크를 예쁜 링크로 변경하십시오.

    <a href="/my/pretty/link">
    
  2. 서버에서 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 개의 섹션으로 나뉩니다.

  1. RewriteRule -다시 쓰기 규칙을 시작합니다
  2. ^blog/([0-9]+)/([A-Za-z0-9-\+]+)/?$ -이것을 패턴이라고 부르지 만, 그냥 규칙의 왼쪽이라고하겠습니다.
  3. blog/index.php?id=$1&title=$2 -대체 규칙 또는 재 작성 규칙의 오른쪽-재 작성하려는 항목
  4. [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 파일이 현재 서버에 있는지 확인하고 파일이 없으면 다시 쓰기를 실행합니다
  • 다시 쓰기는 다른 도메인에 동일한 파일을로드하려고 시도합니다

참고 문헌

스택 오버플로가 많은 시작하는 다른 훌륭한 자원을 :

그리고 새로 온 친절한 정규식 개요 :

자주 사용되는 자리 표시 자

  • .*빈 문자열까지도 일치합니다. 이 패턴을 모든 곳에서 사용하고 싶지는 않지만 종종 마지막 대체 규칙에서 사용합니다.
  • [^/]+경로 세그먼트에 더 자주 사용됩니다. 슬래시 이외의 항목과 일치합니다.
  • \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에서 세그먼트를 확장하도록하는 것이 더 일반적이지만)

    참조 : 어떻게 쿼리 문자열 키 - 값 쌍으로 내 URL 경로 세그먼트를 변환합니까?

  • 선택적 세그먼트
    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에서는 모든 상대 경로 세그먼트에 대한 리터럴 문자로 해석됩니다.

자주 복제 :

일반적인 .htaccess함정

이제 소금 한알로 이것을 가져 가십시오. 모든 조언을 모든 상황에 대해 일반화 할 수있는 것은 아닙니다. 이것은 잘 알려진 몇 가지 명백한 걸림돌에 대한 간단한 요약입니다.

  • 사용 mod_rewrite.htaccess

    디렉토리 별 구성 파일에서 실제로 RewriteRules를 사용하려면 다음을 수행해야합니다.

    • 서버가 AllowOverride All활성화 되어 있는지 확인하십시오 . 그렇지 않으면 디렉토리 별 .htaccess지시문이 무시되고 RewriteRules가 작동하지 않습니다.

    • 분명히 했습니다 mod_rewrite활성화 당신의 httpd.conf모듈 섹션.

    • 각 규칙 목록 앞에 RewriteEngine On스틸을 입니다. mod_rewrite가 암시 적으로 활성화되어 <VirtualHost>있고 <Directory>섹션에서는 디렉토리 별 .htaccess파일을 개별적으로 소환해야합니다.

  • 슬래시 ^/가 일치하지 않습니다

    일반적으로 .htaccessRewriteRule 패턴을 시작하지 않아야 ^/합니다.

     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오류 를 방지하기위한 것 입니다. 일반적으로 달성하는 것은 HTTP 404오류로 사용자를 매기는 것입니다. ( 생각하면 훨씬 사용자 친화적이지 않습니다.)
    • 실제로 더 유용한 로그 항목 또는 서버 알림 메일을 억제합니다. 당신은 없을 거라고 아무도 현명를 당신의 RewriteRules가 작동하지 않을 이유에.

    일반화 된 보호 수단으로 유혹되는 것들은 종종 실제로 장애물로 밝혀졌습니다.

  • RewriteBase필요 하지 않으면 사용 하지 마십시오

    많은 복사 + 붙여 넣기 예에는 RewriteBase /지시문이 포함되어 있습니다 . 어쨌든 암시 적 기본값이됩니다. 따라서 실제로는 필요하지 않습니다. 멋진 VirtualHost 다시 쓰기 체계에 대한 해결 방법이며 일부 공유 호스팅 업체의 DOCUMENT_ROOT 경로를 잘못 추측했습니다.

    더 깊은 하위 디렉토리의 개별 웹 응용 프로그램과 함께 사용하는 것이 좋습니다. 이러한 경우 RewriteRule 패턴을 단축 할 수 있습니다. 일반적으로 디렉토리 별 규칙 세트에서 상대 경로 지정자를 선호하는 것이 가장 좋습니다.

    .htaccess에서 RewriteBase의 작동 방식을 참조하십시오.

  • MultiViews가상 경로가 겹치면 비활성화

    URL 재 작성은 주로 가상 수신 경로 를 지원하는 데 사용됩니다 . 일반적으로 당신은 단지 하나의 디스패처 스크립트 (가 index.php) 또는 몇 개인 핸들러 ( articles.php, blog.php, wiki.php, ...). 후자 유사한 가상 RewriteRule 경로와 충돌 할 수 있습니다 .

    /article/123예를 들어 요청 article.php/123PATH_INFO로 암시 적으로 맵핑 될 수 있습니다 . commonplace RewriteCond !-f+로 규칙을 지키고 !-dPATH_INFO 지원을 비활성화하거나 disable으로 설정해야 Options -MultiViews합니다.

    어떤 당신이 항상 말을하지 해야합니다 . 컨텐츠 협상은 가상 자원에 대한 자동화입니다.

  • 주문이 중요하다

    mod_rewrite에 대해 알고 싶은 모든 것을 참조하십시오 . 여러 RewriteRules를 결합하면 종종 상호 작용이 발생합니다. 이것은 [L]플래그 당 습관적으로 방지 할 수있는 것이 아니라 한 번 정복 한 계획입니다. 가상 경로가 실제 대상 핸들러에 도달 할 때까지 한 규칙에서 다른 규칙으로 가상 경로를 다시 다시 작성할있습니다 .

    그럼에도 불구하고 당신은 것입니다 종종 가장 구체적인 규칙 (고정 문자열이 원하는 /forum/…패턴, 또는 더 제한적인 자리 [^/.]+에서) 초기 규칙을. 일반적인 말 괄호 규칙 ( .*)이 나중 규칙 에 더 잘 남습니다 . (예외는 RewriteCond -f/-d기본 블록으로서의 보호입니다.)

  • 스타일 시트 및 이미지 작동이 중지됩니다

    가상 디렉터리 구조를 도입하면 /blog/article/123HTML의 상대 리소스 참조 (예 :)에 영향을줍니다 <img src=mouse.png>. 다음으로 해결할 수 있습니다.

    • 서버 절대 참조 만 사용 href="/old.html"하거나src="/logo.png"
    • 종종 <base href="/index">HTML <head>섹션 에 추가하면 됩니다 . 이것은 이전에 있었던 것에 대한 상대적 참조를 암시 적으로 리 바인드합니다.

    다른 RewriteRules 를 만들어 원래 위치 로 리 바인드 .css하거나 .png경로를 지정할 수도 있습니다. 그러나 그것은 불필요하거나 여분의 리디렉션이 발생하고 캐싱을 방해합니다.

    참조 : CSS, JS와 이미지가 꽤 URL이 표시되지 않습니다

  • 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=ymod_rewrite는 기본값 당 상대 경로와 비교하기 때문에을 일치시킬 수 없습니다 . 그러나 다음을 통해 별도로 일치시킬 수 있습니다.

     RewriteCond %{QUERY_STRING} \b(?:param)=([^&]+)(?:&|$)
     RewriteRule ^add/(.+)$  add/%1/$1  # ←──﹪₁──┘
    

    쿼리 문자열 변수를 mod_rewrite와 어떻게 일치시킬 수 있습니까?를 참조하십시오 .

  • .htaccess vs. <VirtualHost>

    디렉토리 별 구성 파일에서 RewriteRules를 사용하는 경우 정규 표현식 성능에 대한 걱정은 의미가 없습니다. Apache는 공통 라우팅 프레임 워크를 사용하여 PHP 프로세스보다 더 긴 컴파일 된 PCRE 패턴을 유지합니다. 트래픽이 많은 사이트의 경우 규칙 테스트가 완료되면 규칙 세트를 가상 호스트 서버 구성으로 이동하는 것을 고려해야합니다.

    이 경우 선택적 ^/?디렉토리 구분 기호 접두사를 선호하십시오 . 이를 통해 PerDir과 서버 구성 파일간에 RewriteRules를 자유롭게 이동할 수 있습니다.

  • 무언가 가 작동하지 않을 때마다

    걱정하지 마십시오.

    • 비교 access.logerror.log

      종종 RewriteRule이 error.logand 및 을보고 오작동하는 방식을 파악할 수 있습니다 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.logerror.log기존 규칙으로 해결 된 사항을 확인합니다. 더 나은 아직 rewrite.log요약.

      이를 통해보다 빠르고 정확한 답변을 얻을 수 있으며 다른 사람들에게 더 유용합니다.

  • 당신의 코멘트 .htaccess

    어딘가에서 예제를 복사하는 경우을 포함하도록주의하십시오 # comment and origin link. 속성을 생략하는 것은 나쁜 방법 일 뿐이지 만 나중에 유지 관리에 심각한 영향을줍니다. 모든 코드 또는 튜토리얼 소스를 문서화하십시오. 특히, 미지의 동안에는 마법의 블랙 박스처럼 취급하지 않는 것에 더 관심을 가져야합니다.

  • "SEO"가 아닙니다. URL

    면책 조항 : 단지 애완 동물 친구. 당신은 종종 "SEO"링크 또는 무언가로 불리는 꽤 URL 재 작성 체계를 듣습니다. 이것은 인터넷 검색 예제에 유용하지만 날짜가 지난 잘못된 이름입니다.

    현대적인 검색 엔진의 아무도는 정말 방해하지 않습니다 .html.php패스 세그먼트 (segment), 또는에서 ?id=123그 문제에 대한 쿼리 문자열. AltaVista와 같은 오래된 검색 엔진은 잠재적으로 모호한 액세스 경로를 가진 웹 사이트를 크롤링 하지 않았습니다 . 최신 크롤러는 종종 깊은 웹 리소스를 원합니다.

    개념적으로 "예쁜"URL을 사용해야하는 것은 웹 사이트를 사용자에게 친숙 하게 만드는 것 입니다.

    1. 읽기 쉽고 명백한 리소스 체계가 있습니다.
    2. URL의 수명이 길다 (AKA permalinks ).
    3. 를 통해 검색 가능성 제공 /common/tree/nesting.

    그러나 적합성에 대한 고유 한 요구 사항을 희생하지 마십시오.

도구

대부분의 GET 매개 변수 URL에 대해 RewriteRules를 생성하는 다양한 온라인 도구가 있습니다.

대부분 [^/]+일반 자리 표시자를 출력 하지만 사소한 사이트에는 충분합니다.


mod_rewrite의 대안

RewriteRules를 사용하지 않고도 많은 기본 가상 URL 체계를 달성 할 수 있습니다. 아파치는 PHP 스크립트를 .php확장 없이 , 그리고 가상의 PATH_INFO인수 로 호출 할 수있게 한다.

  1. 사용 PATH_INFO , 루크

    요즘 AcceptPathInfo On은 종종 기본적으로 활성화되어 있습니다. 기본적으로 .php다른 리소스 URL이 가상 인수를 수행하도록 허용 합니다.

    http://example.com/script.php/virtual/path
    

    이제 이것은 추가 인수를 원하는 /virtual/path대로 $_SERVER["PATH_INFO"]처리 할 수있는 곳 으로 PHP에 표시됩니다 .

    이것에 아파치 별도의 입력 경로 세그먼트를 구비 한 편리하지 $1, $2, $3별개로 전달 $_GETPHP하는 변수. 적은 노력으로 "예쁜 URL"을 모방 할뿐입니다.

  2. 확장 을 숨기려면 MultiViews 활성화.php

    .phpURL에서 "파일 확장자"를 피하는 가장 간단한 옵션 은 다음과 같습니다.

    Options +MultiViews
    

    일치하는 기본 이름으로 인해 Apache에서 article.phpHTTP 요청을 선택 합니다 /article. 그리고 이것은 위에서 언급 한 PATH_INFO 기능과 함께 잘 작동합니다. 그래서 당신은 같은 URL을 사용할 수 있습니다 http://example.com/article/virtual/title. 여러 PHP 호출 지점 / 스크립트가있는 전통적인 웹 응용 프로그램이있는 경우 의미가 있습니다.

    MultiViews는 다른 / 광범위한 목적을 가지고 있습니다. 그것은 초래 아주 작은 아파치가 항상 일치하는 basename이 다른 파일을 찾습니다 있기 때문에, 성능 저하. 그것은 실제로 의미있어 내용 협상 브라우저 (예 : 가용 자원 중 가장 좋은 대안을받을 수 있도록, article.en.php, article.fr.php, article.jp.mp4).

  3. 확장없는 .php스크립트를 위한 SetType 또는 SetHandler

    .phpURL에서 접미사 를 피하는보다 직접적인 접근 방식 은 다른 파일 체계에 맞게 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정적 자원 등), 업로드 / 디렉토리 등

  4. 다른 Apache 재 작성 체계

    많은 옵션 중에서 Apache는 RewriteRules mod_alias와 마찬가지로 작동하는 기능을 제공 합니다 mod_rewrite. 그러나 대부분은 <VirtualHost>디렉토리 별 .htaccess구성 파일이 아닌 섹션 에서 설정해야 합니다.

    • ScriptAliasMatch주로 CGI 스크립트 용이지만 PHP에서도 작동합니다. 그것은 어떤 식 으로든 정규 표현식을 허용합니다 RewriteRule. 실제로 모든 전면 컨트롤러를 구성하는 것이 가장 강력한 옵션 일 것입니다.

    • 그리고 평범한 Alias몇 가지 간단한 다시 쓰기 체계도 도움이됩니다.

    • ErrorDocumentPHP 스크립트가 가상 경로를 처리하도록 일반 지시문도 사용할 수 있습니다. 그러나 이것은 해결하기 어려운 해결책이지만 GET 요청 이외의 것은 금지하고 error.log를 정의에 따라 넘칩니다.

    추가 팁 http://httpd.apache.org/docs/2.2/urlmapping.html참조 하십시오 .

참고 URL : https://stackoverflow.com/questions/20563772/reference-mod-rewrite-url-rewriting-and-pretty-links-explained

반응형