쿼리 문자열 물음표를 밑줄로 바꾸는 Nginx 다시 쓰기 규칙


16

전체 웹 사이트를 정적 HTML로 미러링하려면

내가 좋아하는 URL을 변환하고 싶습니다 http://example.com/script.php?t=12http://example.com/script.php_t=12.

?URL의 공지 가로 변환 중입니다 _.

이를 통해 nginx 또는 apache wget는 PHP 파일이 아닌 각 URL에 대해 하나의 파일 에서 얻은 원시 HTML로 디스크에서 이러한 파일을 제공 할 수 있습니다 .

Nginx URL 재 작성을 통해 그렇게 할 수 있습니까?


확실히 가능하지만 정말 이상합니다. 무엇을 원하십니까?
Alexey Ten

2
이 방법의 한 가지 문제점은 URL의 여러 GET 매개 변수가 임의 순서로있을 수 있으며이 변환을 수행하면 URL의 의미가 변경된다는 것입니다.
Tero Kilkanen

정적 html로 오래된 포럼을 보관하기위한 것이지만,이 작업 http://example.com/script.php?a=1&t=3을하려면 매우 멋진 재 작성 작업이 필요합니다
Sam Saffron

1
@tero 쿼리 문자열 URL은 실제로 항상 같은 순서입니다. 따라서 이것은 문제가되지 않습니다.
Jeff Atwood

1
인수가 아닌 다른이 될 수 있도록 @chx 그것은 오래된 포럼 보관의 t같은 f, u
Arpit 잘란

답변:


15

try_files를 사용 하여이 작업을 수행했습니다.

location / {
    try_files "${uri}_${args}" 404.html;
}

그러면 "?"대신 "_"로 제공 한 패턴의 이름을 딴 디스크에서 파일을 찾습니다.

추가 구성은 이미지 또는 스타일 시트와 같은 정적 파일을 저장 한 방법에 따라 다릅니다. 다음과 같이 쿼리 문자열 양식 디스크없이 읽도록 대체를 추가 할 수 있습니다.

location / {
    try_files "${uri}_${args}" $uri 404.html;
}

1
매우 흥미로운 접근 방법이지만 잠재적 인 모든 URL에서 잠재적 인 디스크 읽기 및 "파일을 찾을 수 없음"이 발생합니까?
Jeff Atwood

에서 try_files : "확인 지정된 순서로 파일의 존재와 요청 처리를 위해 먼저 발견 파일을 사용합니다." 따라서 이로 인해 질문의 URL에 대한 추가 디스크 읽기가 발생하지 않습니다.
Matthias Bayer

1
좋아, 우리가 그것을 넣어 우리는 일을 location ~ \.php$할 수 try_files있지만 작동하지 않습니다location /
Jeff Atwood

:) 중괄호를 사용하는 예를 들어, 한
다닐라 Vershinin

4

라인을 따라 뭔가 :

location ~ \.php$ {
  # only rewrite URL's with args
  if ($args != '') {
    rewrite .* "${uri}_${args}?" last;
  }
}

당신은 ?내 대답을 사용하지 않았습니다.
chx

귀하의 답변에 관해서는?에 관해서는 정확합니다. 실제 서버에서 테스트하는 데 시간이 걸렸으므로 게시 할 때까지는 보지 못했습니다. 그리고 당신은 바람직하지 않을 수있는 "_"로 변형에 대한 인수없이 모든 URL을 다시 작성합니다.
Max Gashkov

try_files가있는 Matthias의 솔루션이 실제로 이보다 더 좋습니다.
Max Gashkov

.*첫 번째 다시 쓰기 매개 변수에 더 엄격한 절을 지정할 때 if없이 수행 할 수 있습니다 . 이것은 매우 도움이됩니다!
Jeff Atwood

@JeffAtwood 나는 그것이 가능하지 않다고 생각한다-nginx 다시 쓰기 (및 위치) 패턴은 쿼리 문자열 전에 URL의 일부에 적용되어야합니다.
Max Gashkov

1

바닐라 nginx 로이 작업을 수행 할 수는 없다고 생각하지만 nginx 용 Lua 모듈을 설치하려는 경우 ( http://wiki.nginx.org/HttpLuaModule ) 할 수 있습니다.

server {
    server_name so.dev;
    listen 80;

    location / {

        root /tmp;

        rewrite_by_lua '
            local uri = ngx.var.uri
            local params = ngx.req.get_uri_args(0)

            for key, value in pairs(params) do
                uri = string.format("%s_%s=%s", uri, key, value)
            end

            ngx.req.set_uri(uri)
            ngx.req.set_uri_args({})
        ';

    }
}

로컬에서 테스트했으며 원하는 것을하는 것 같습니다. 다른 매개 변수를 앰퍼샌드로 구분하여 유지하려면 rewrite_by_lua 블록을 다음과 같이 변경하십시오.

local uri = ngx.var.uri
local param_string = ""
local params = ngx.req.get_uri_args(0)
local separator = ""

for key, value in pairs(params) do
    param_string = param_string .. separator .. key .. "=" .. value
    separator = "&"
end

ngx.req.set_uri(uri .. "_" .. param_string)
ngx.req.set_uri_args({})

1

이것은 nginx / 1.6.2에서 작동합니다.

rewrite ^/.*\.php$ "${uri}_${args}";

그러나 개인적 으로 어떤 경우에는try_files 원래 URI로 대체되는 솔루션을 사용 합니다 .

try_files $uri "${uri}_${args}";

예를 들어 script.php디스크에 있으면 먼저 시도해보고 아무것도 없으면으로 이동합니다 script.php_t=12. try_files최신 버전의 nginx가 필요합니다.

그리고 이것이 충분하지 않으면 다음과 같이 할 수 있습니다 if:

return 301 "${uri}_${args}";

나는 이것을 좋아하지만 try_files 비트를 실제로 작동시킬 수는 없지만 다시 쓰기 작동합니다. ( ?재 작성 끝에 a 를 추가 하면 쿼리 매개 변수가 추가되지 않습니다.)
Jeff Atwood

@JeffAtwood try_files$uri일치하는 위치 블록이나 파일 ( 아르 기가없는 요청) 이있는 경우 중단됩니다. 그렇 습니까?
AD7six

@JeffAtwood ?는 정적 파일에 눈에 띄는 영향을 미치지 않으며 액세스 로그에는 추가 쿼리 만 표시됩니다. 관심이 있다면, 물음표를 추가하십시오
sanmai

0

위키는 말한다

?를 지정하면? 다시 쓰기가 끝나면 Nginx는 원래 $ args (인수)를 삭제합니다.

그럼 rewrite ^ ${uri}_$args? last;작동해야합니다.


nginx가 해당 규칙 세트로 다시 시작하지 못합니다 –rewrite ^ $uri_$args? last;
Jeff Atwood

결정된. $ -bleeds-over-the-variables는 PHP가 마음에 들었습니다.
chx

개정 된 버전에서도 nginx가 다시 시작되지
Jeff Atwood

0

위에서 제안한 답변이 효과가 있습니다. 그러나 URL이 얼마나 민감한 지 알 수 있습니다. nginx는 파일 이름이 서버에 먼저 존재하는지 확인하려고 시도하기 때문에 추가 매개 변수가 파일을 제거합니다.

http://example.com/script.php?t=12 // works 
http://example.com/script.php?t=12&_utm=twitter // not work

내 제안은 URL을 그대로두고 php로 올바른 파일로 라우팅하는 것입니다. t매개 변수에 액세스 할 수 있습니다 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.