[nginx] NGINX의 프록시 응답에서 URL을 어떻게 다시 작성합니까?

나는 mod_proxy_html과 함께 Apache를 사용하는 데 익숙하며 NGINX로 비슷한 것을 달성하려고 노력하고 있습니다. 특정 사용 사례는 루트 컨텍스트의 서버에서 포트 8080의 Tomcat에서 실행되는 관리 UI가 있다는 것입니다.

http://localhost:8080/

포트 80에서이를 표시해야하지만이 호스트에서 실행중인 NGINX 서버에 다른 컨텍스트가 있으므로 다음 위치에서 시도하고 액세스하고 싶습니다.

http://localhost:80/admin/

다음과 같은 매우 간단한 서버 블록이이를 수행하기를 바랐지만 그렇지 않습니다.

server {
    listen  80;
    server_name screenly.local.akana.com;

    location /admin/ {
        proxy_pass http://localhost:8080/;
    }
}

문제는 반환 된 콘텐츠 (html)에 모두 루트 컨텍스트에서 액세스되는 스크립트 및 스타일 정보에 대한 URL이 포함되어 있으므로이 URL을 / 대신 / admin /으로 시작하도록 다시 작성해야합니다.

NGINX에서 어떻게해야합니까?



답변

우리는 먼저 proxy_pass에 대한 문서를 주의 깊게 그리고 완전히 읽어야 합니다 .

업스트림 서버로 전달되는 URI는 “proxy_pass”지시문이 URI와 함께 사용되는지 여부에 따라 결정됩니다. proxy_pass 지시문의 후행 슬래시는 URI가 있고과 같음을 의미합니다 /. 후행 슬래시가 없으면 모자 URI가 없음을 의미합니다.

URI가있는 Proxy_pass :

location /some_dir/ {
    proxy_pass http://some_server/;
}

위의 경우 다음 프록시가 있습니다.

http:// your_server/some_dir/ some_subdir/some_file ->
http:// some_server/          some_subdir/some_file

기본적으로 요청 경로를에서 로 변경하려면 /some_dir/로 대체됩니다 .//some_dir/some_subdir/some_file/some_subdir/some_file

URI없는 Proxy_pass :

location /some_dir/ {
    proxy_pass http://some_server;
}

두 번째 (후행 슬래시 없음) : 프록시는 다음과 같이됩니다.

http:// your_server /some_dir/some_subdir/some_file ->
http:// some_server /some_dir/some_subdir/some_file

기본적으로 전체 원래 요청 경로는 변경없이 전달됩니다.


따라서 귀하의 경우에는 원하는 것을 얻으려면 후행 슬래시를 드롭 해야하는 것 같습니다.


경고

자동 재 작성은 proxy_pass에서 변수를 사용하지 않는 경우에만 작동합니다. 변수를 사용하는 경우 직접 다시 작성해야합니다.

location /some_dir/ {
  rewrite    /some_dir/(.*) /$1 break;
  proxy_pass $upstream_server;
}

재 작성이 작동하지 않는 다른 경우가 있기 때문에 문서를 읽는 것이 필수입니다.


편집하다

귀하의 질문을 다시 읽으면 html 출력을 편집하고 싶다는 것을 놓친 것 같습니다.

이를 위해 sub_filter 지시문을 사용할 수 있습니다 . 뭔가 …

location /admin/ {
    proxy_pass http://localhost:8080/;
    sub_filter "http://your_server/" "http://your_server/admin/";
    sub_filter_once off;
}

기본적으로 교체하려는 문자열과 교체 문자열


답변

데이터 압축을 사용하는 백엔드 서버의 경우 첫 번째 “sub_filter”전에 다음 지시문을 설정해야 할 수도 있습니다.

proxy_set_header Accept-Encoding "";

그렇지 않으면 작동하지 않을 수 있습니다. 예를 들어 다음과 같습니다.

location /admin/ {
    proxy_pass http://localhost:8080/;
    proxy_set_header Accept-Encoding "";
    sub_filter "http://your_server/" "http://your_server/admin/";
    sub_filter_once off;
}


답변

다음 nginx 구성 예제를 사용할 수 있습니다.

upstream adminhost {
  server adminhostname:8080;
}

server {
  listen 80;

  location ~ ^/admin/(.*)$ {
    proxy_pass http://adminhost/$1$is_args$args;
    proxy_redirect off;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Host $server_name;
  }
}


답변