nginx - proxy_pass на user_agent

У меня есть сайт SPA,где мне нужно загрузить соответствующие теги для каждой подстраницы, но это не так просто из самих подстраниц, поэтому я сделал отдельный адрес, по которому боты Facebook или Twitter могут загружать соответствующие значения OpenGraph. Это выглядит так:

Исходный URL : http://website.com/contents/1
Маршрут с тегами OG для этого URL : http: // website .com / og / contents / 1

Я хочу использовать для этого proxy_pass с учетом только конкретного User-Agent , однако следующая конфигурация не работает, т.е. нет перенаправления:

    location /contents {
        resolver 127.0.0.11 ipv6=off valid=5m;

        if ($http_user_agent ~* ("(facebookexternalhit)\/(.*)|(Twitterbot)\/(.*)")) {
            proxy_pass http://$host:8080/open-graph$request_uri;
        }
    }

Кто-нибудь видит, где плохо?

0
задан 11 February 2020 в 00:45
1 ответ

Сначала, когда вам нужна какая-то строка в вашей конфигурации nginx, вы можете использовать одинарные или двойные кавычки или не использовать их вообще (если ваша строка не содержит специальных символов, таких как пробелы, фигурные скобки и т. д.). В вашем случае nginx предполагает, что вы не используете кавычки (потому что вы начинаете строку с круглой скобки), поэтому строка регулярного выражения, обрабатываемая nginx, равна ("(facebookexternalhit) \ / (. *) | (Twitterbot) \ / (. *)") , включая круглые скобки и двойные кавычки. Он не будет соответствовать ни одному пользовательскому агенту, если он не содержит "facebookexternalhit / ..." или "twitterbot / ..." подстроки с двойными кавычками .

Во-вторых, вам не нужно так много захватов (на самом деле они вам вообще не нужны, потому что вы их не используете позже). Эти записи заставляют nginx тратить дополнительные ресурсы при сопоставлении строки с регулярным выражением (это не то, что вам нужно в системе с высокой нагрузкой). Следующий блок должен работать так, как вы ожидали (обратите внимание, что символ / не нужно экранировать, хотя его экранирование не нарушит регулярное выражение):

    if ($http_user_agent ~* (facebookexternalhit|twitterbot)/) {
        proxy_pass http://$host:8080/open-graph$request_uri;
    }

Однако это не очень хорошо решение. Лучше избегать if конструкций , если вы не используете только директивы ngx_http_rewrite_module внутри блока if . В нашем случае nginx создаст две конфигурации: первая будет использоваться, если строка User-Agent совпадает с регулярным выражением, вторая будет использоваться, если это не так. Я настоятельно рекомендую не использовать здесь конструкцию if . Вместо этого вы можете использовать преобразование map :

map $http_user_agent $og_prefix {
    ~*(facebookexternalhit|twitterbot)/  /open-graph;
}

server {
    ...
    location /contents {
        resolver 127.0.0.11 ipv6=off valid=5m;
        proxy_pass http://$host:8080$og_prefix$request_uri;
    }
    ...
}

Значение переменной $ og_prefix будет / open-graph , если строка User-Agent соответствует регулярному выражению или в противном случае - пустая строка.

0
ответ дан 26 February 2020 в 00:42

Теги

Похожие вопросы