nginx를 사용하여 proxy_pass를 통해 쿼리 문자열 매개 변수를 어떻게 전달할 수 있습니까?


114
upstream apache {
   server 127.0.0.1:8080;
}
server{
   location ~* ^/service/(.*)$ {
      proxy_pass http://apache/$1;
      proxy_redirect off;
   }
 }

위의 스 니펫은 URL에 "service"문자열이 포함 된 요청을 다른 서버로 리디렉션하지만 쿼리 매개 변수는 포함하지 않습니다.

답변:


163

로부터 proxy_pass의 문서 :

특별한 경우는 proxy_pass 문에서 변수를 사용하는 것입니다. 요청 된 URL은 사용되지 않으며 대상 URL을 직접 구성 할 책임은 전적으로 사용자에게 있습니다.

대상에서 $ 1을 사용하고 있기 때문에 nginx는 정확히 무엇을 전달해야하는지 알려주기 위해 사용자에게 의존합니다. 두 가지 방법으로이 문제를 해결할 수 있습니다. 첫째, proxy_pass로 uri의 시작 부분을 제거하는 것은 간단합니다.

location /service/ {
  # Note the trailing slash on the proxy_pass.
  # It tells nginx to replace /service/ with / when passing the request.
  proxy_pass http://apache/;
}

또는 정규식 위치를 사용하려면 인수 만 포함하면됩니다.

location ~* ^/service/(.*) {
  proxy_pass http://apache/$1$is_args$args;
}

1
나는 당신이 후자를 할 수 있다고 믿지 않습니다. 나는 시도했고 nginx는 나에게 불평했다.
duma

3
어떻게 불평? 방금 nginx 1.3.4에서 테스트했는데 잘 작동했습니다.
kolbyjack

흠 .. 지금은 기억 나지 않습니다. :(하지만 "~ *"와 관련이있는 것 같습니다.하지만 방금 확인한 결과 nginx 1.2.3 (홈 브루를 통해)이 있습니다. 그게 다일까요?
두마

"proxy_redirect 기본"변수 "proxy_pass"지시문과 함께 사용할 수 없습니다
장 - 필립 카루 아나

1
재 사용해야합니다 location /service/ { rewrite ^\/service\/(.*) /$1 break; proxy_pass http://apache; }
앤드류 Arnautov

27

~대신 kolbyjack의 두 번째 접근 방식을 약간 수정 한 버전을 사용합니다 ~*.

location ~ ^/service/ {
  proxy_pass http://apache/$uri$is_args$args;
}

10

@kolbyjack 코드를 수정하여 작동하도록했습니다.

http://website1/service
http://website1/service/

매개 변수 포함

location ~ ^/service/?(.*) {
    return 301 http://service_url/$1$is_args$args;
}

1
이렇게하면 리디렉션하기 전에 서버가 클라이언트에 301 응답을 반환하게됩니다. proxy_pass위 의 지시문은 서버 측에서 리디렉션을 수행합니다.
누가 복음 피터슨

1
검색어 매개 변수에 URL (%)로 인코딩 된 문자가 포함되어 있으면 중단됩니다. 대신 Andrew의 대답을 사용하십시오.
David Weber

9

rewrite를 사용하여 proxy_pass를 사용하여 params를 전달해야합니다. s3에 angularjs 앱 배포를 위해 한 예입니다.

S3 정적 웹 사이트 호스팅 모든 경로를 Index.html로 라우팅

당신의 필요에 채택 될 것입니다

location /service/ {
    rewrite ^\/service\/(.*) /$1 break;
    proxy_pass http://apache;
}

http://127.0.0.1:8080/query/params/ 에서 끝내려면

http://127.0.0.1:8080/service/query/params/ 에서 끝내려면 다음과 같은 것이 필요합니다.

location /service/ {
    rewrite ^\/(.*) /$1 break;
    proxy_pass http://apache;
}

1
이것은 경로 매개 변수 ( /path/params)를 잘 처리하지만 쿼리 매개 변수 ( ) 는 처리 하지 않는 것 같습니다 ?query=params.
Will

아, 내 실수입니다. 쿼리 매개 변수는 자동으로 추가되어야합니다 (테스트 중입니다).

2

github 요점 https://gist.github.com/anjia0532/da4a17f848468de5a374c860b17607e7

#set $token "?"; # deprecated

set $token ""; # declar token is ""(empty str) for original request without args,because $is_args concat any var will be `?`

if ($is_args) { # if the request has args update token to "&"
    set $token "&";
}

location /test {
    set $args "${args}${token}k1=v1&k2=v2"; # update original append custom params with $token
    # if no args $is_args is empty str,else it's "?"
    # http is scheme
    # service is upstream server
    #proxy_pass http://service/$uri$is_args$args; # deprecated remove `/`
    proxy_pass http://service$uri$is_args$args; # proxy pass
}

#http://localhost/test?foo=bar ==> http://service/test?foo=bar&k1=v1&k2=v2

#http://localhost/test/ ==> http://service/test?k1=v1&k2=v2

1

쿼리 문자열없이 리디렉션하려면 수신 포트 줄 아래의 서버 블록에 아래 줄을 추가합니다.

if ($uri ~ .*.containingString$) {
           return 301 https://$host/$uri/;
}

쿼리 문자열 사용 :

if ($uri ~ .*.containingString$) {
           return 301 https://$host/$uri/?$query_string;
}

1
nginx 문서는 if가능한 경우 사용하지 않기 위해 명시 적입니다 . 이 경우 location다른 답변에 표시된 것처럼 솔루션이 옳을 수 있습니다 .
Andrés Morales

2
는 단점이있다하더라도 어쨌든 또 하나 개의 솔루션은 더 나은
드미트리 Malugin

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