Как сделать так, чтобы try_files с несколькими запасными вариантами работали в nginx? - PullRequest
0 голосов
/ 31 января 2019

У меня nginx работает как прокси для двух серверов приложений: daphne и gunicorn

И мое webApp - это одностраничное приложение AngularJs.Поэтому мне нужно использовать prerender.io, чтобы помочь ботам сканировать сайт.

Мой файл nginx:

upstream ex_server{
 server unix:/home/webapps/ex/run/gunicorn.sock fail_timeout=0;
}

upstream channels-backend {
    server 0.0.0.0:8001;
}

server {
    server_name example.com;
    listen 80; 
        rewrite ^ https://$http_host$request_uri permanent;
}

server {
    server_name example.com;

    listen 443 ssl;
    ssl_certificate /etc/ssl/_cert_chain.crt;
    ssl_certificate_key /etc/ssl/_in.key; 

    root /usr/share/nginx/html;

    server_name _;

    location / {
            try_files /$uri @prerender;
            #try_files /$uri @prerender @proxy_to_main_app; <= I wanted this
    }

    location @proxy_to_main_app {
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto https;  # <-
            proxy_set_header Host $http_host;
            proxy_redirect off;
            #proxy_buffering off;

            try_files $uri @proxy_to_daphne_app;

        if (!-f $request_filename) {
            proxy_pass http://ex_server;
            break;
        }
    }

location @proxy_to_daphne_app {
    proxy_pass http://channels-backend;
    proxy_set_header X-Forwarded-Proto https;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";

    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;
}

location @prerender {
    proxy_set_header X-Prerender-Token RMVQxJkVVugDjcPgHakN;
    set $prerender 0;
    if ($http_user_agent ~* "googlebot|bingbot|yandex|baiduspider|twitterbot|facebookexternalhit|rogerbot|linkedinbot|embedly|quora link preview|showyoubot|outbrain|pinterest|slackbot|vkShare|W3C_Validator") {
        set $prerender 1;
    }
    if ($args ~ "_escaped_fragment_") {
        set $prerender 1;
    }
    if ($http_user_agent ~ "Prerender") {
        set $prerender 0;
    }
    if ($uri ~* "\.(js|css|xml|less|png|jpg|jpeg|gif|pdf|doc|txt|ico|rss|zip|mp3|rar|exe|wmv|doc|avi|ppt|mpg|mpeg|tif|wav|mov|psd|ai|xls|mp4|m4a|swf|dat|dmg|iso|flv|m4v|torrent|ttf|woff|svg|eot)") {
        set $prerender 0;
    }

    resolver 8.8.8.8;

    if ($prerender = 1) {
        set $prerender "service.prerender.io";
        rewrite .* /$scheme://$host$request_uri? break;
        proxy_pass http://$prerender;
    }
    if ($prerender = 0) { 
        # here is the problem. when $prerender=0 means it isn't the crawler requesting a rendered page but an actual user. So, we need to show path to our webApp as usual.
    }
}

    }

Как вы можете заметить, у меня есть три варианта отката @prerender, @proxy_to_main_app,@proxy_to_daphne_app.

Теперь @prerender работает нормально.Но if($prerender=0), мне нужно попробовать @proxy_to_main_app, т. Е.

if($prerender=0){
    try_files @proxy_to_main_app
}

Но это не работает.nginx не позволяет try_files внутри, если.

Пожалуйста, помогите с обходным решением.Я прошел через все другие сообщения.Но не поможет.

1 Ответ

0 голосов
/ 31 января 2019

В файлах try_files может быть только одно @ местоположение, поэтому вы можете попробовать объединить их.И соответствует ли $ uri вашим файлам try_files каким-либо файлам в этой файловой системе, или вы просто отправляете запросы?Будет ли что-то вроде этой работы?

upstream ex_server{
 server unix:/home/webapps/ex/run/gunicorn.sock fail_timeout=0;
}

upstream channels-backend {
    server 0.0.0.0:8001;
}

server {
    server_name example.com;
    listen 80; 
        rewrite ^ https://$http_host$request_uri permanent;
}

server {
    server_name example.com;

    listen 443 ssl;
    ssl_certificate /etc/ssl/_cert_chain.crt;
    ssl_certificate_key /etc/ssl/_in.key; 

    root /usr/share/nginx/html;

    server_name _;

    location / {
            proxy_set_header X-Prerender-Token YOUR_TOKEN;
            set $prerender 0;
            if ($http_user_agent ~* "googlebot|bingbot|yandex|baiduspider|twitterbot|facebookexternalhit|rogerbot|linkedinbot|embedly|quora link preview|showyoubot|outbrain|pinterest|slackbot|vkShare|W3C_Validator") {
                set $prerender 1;
            }
            if ($args ~ "_escaped_fragment_") {
                set $prerender 1;
            }
            if ($http_user_agent ~ "Prerender") {
                set $prerender 0;
            }
            if ($uri ~* "\.(js|css|xml|less|png|jpg|jpeg|gif|pdf|doc|txt|ico|rss|zip|mp3|rar|exe|wmv|doc|avi|ppt|mpg|mpeg|tif|wav|mov|psd|ai|xls|mp4|m4a|swf|dat|dmg|iso|flv|m4v|torrent|ttf|woff|svg|eot)") {
                set $prerender 0;
            }

            resolver 8.8.8.8;

            if ($prerender = 1) {
                set $prerender "service.prerender.io";
                rewrite .* /$scheme://$host$request_uri? break;
                proxy_pass http://$prerender;
            }

            try_files /$uri @proxy_to_main_app;
    }

    location @proxy_to_main_app {
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto https;  # <-
            proxy_set_header Host $http_host;
            proxy_redirect off;
            #proxy_buffering off;

            try_files $uri @proxy_to_daphne_app;

        if (!-f $request_filename) {
            proxy_pass http://ex_server;
            break;
        }
    }

    location @proxy_to_daphne_app {
        proxy_pass http://channels-backend;
        proxy_set_header X-Forwarded-Proto https;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";

        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;
    }

}
...