nginx 無法 proxy_pass header 301 302

官方說明文件:
https://www.nginx.com/blog/creating-nginx-rewrite-rules/

 

解法:

This is not ideal and it would be far better to have a clean workflow instead of doing this. But for curiosity, this could be informative to people that would wonder if it’s possible.

Yes it is, using a combination of error_page, rewrite, map, proxy_intercept_errors and proxy_redirect directives and $upstream_http var pattern.

Keep in mind that it’s going far off the path nginx is designed to be driven on.

map $upstream_http_location $redirect_uri {
    "~http://[^/]+/(?<location_uri>.*)$" "$location_uri";
}

upstream origin {
    server origin1.com;
}

server {

    listen 80;
    server_name nginx-front.com;

    proxy_set_header Host "origin1.com";
    proxy_redirect http://origin1.com/ /;

    location ~ ^/hls/(\w+)\.mp4\.m3u8$ {
        proxy_pass http://origin/m3ugen/segsrc/\.mp4;
        proxy_intercept_errors on;
        error_page 301 302 = @handler;    
    }

    location @handler {
        rewrite ^ /$redirect_uri break;
        proxy_pass http://origin;
    }

}

It is possible for nginx to intercept the 302 response code and process internally. I set up a test scenario which worked using this:

location /some/uri/ {
    error_page 302 = @fallback;
    proxy_intercept_errors on;
    proxy_pass ...;
}
location @fallback {
    rewrite ^ /some/other/uri last;
}

This would of course be a blanket intercept without regard for the value of the response headers, but that may be adequate for your requirement. See this and this for more.


I succeeded in solving a more generic case when a redirect location can be any external URL.

server {
    ...

    location / {
        proxy_pass http://backend;
        # You may need to uncomment the following line if your redirects are relative, e.g. /foo/bar
        #proxy_redirect / /;
        proxy_intercept_errors on;
        error_page 301 302 307 = @handle_redirects;
    }

    location @handle_redirects {
        set $saved_redirect_location '$upstream_http_location';
        proxy_pass $saved_redirect_location;
    }
}

Alternative approach, which is closer to what you describe, is covered in ServerFault answer to this question: http://serverfault.com/questions/641070/nginx-302-redirect-resolve-internally

 

修改 sample:
https://gist.github.com/sirsquidness/710bc76d7bbc734c7a3ff69c6b8ff591

 

資料來源:
http://serverfault.com/questions/641070/nginx-302-redirect-resolve-internally

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *