У меня есть веб-сайт с nginx, который возвращает index.html (одностраничное приложение для реагирования) почти для всех запросов.Любой запрос практически для любого пути (например, /некоторые/статья
) тоже вернется index.html
, и приложение реакции (маршрутизатор реакции) преобразует путь в вызовы API. Вот как это работает, и это нельзя изменить (веб-сайт огромен, это слишком много работы, и я все равно не в состоянии это изменить).
Для этих запросов должно быть два исключения:
- Все запросы, начинающиеся с пути /api/*, передаются вышестоящему серверу (серверу приложений). Таким образом, другой бэкэнд будет обрабатывать все фактические запросы API.
- Другим исключением должны быть внешние хиты Facebook. Для этого существует другая конечная точка в /api/open_graph на сервере приложений. Например. /api/open_graph должен быть указан перед исходным путем. Эта конечная точка возвращает фактический контент (а не обычное одностраничное приложение, которое не имеет реального контента). Формат также отличается — обычные вызовы API обычно возвращают данные JSON, а конечная точка open_graph возвращает простой HTML.
Пример конфигурации nginx:
вверх по течению www {
# ...
}
сервер {
# ...
# Используйте /api/open_graph в апстриме для внешних обращений в Facebook
если ($http_user_agent ~* "^facebookexternalhit.*$") {
переписать ^/(.*)$ /api/open_graph/$1 навсегда;
}
# API-запросы будут отправляться вверх по течению
расположение ~ ^/api/ {
прокси_пароль http://www;
proxy_read_timeout 90;
proxy_redirect http://www https://example.com;
}
# Все остальные запросы используют реагирующее приложение,
# react router обрабатывает все дальнейшие запросы
место расположения / {
индекс index.html;
error_page 404 = 200 /index.html;
}
}
Приведенный выше конфиг работает следующим образом:
# curl -A "facebookexternalhit" -s -D - -o /dev/null https://example.com/article1
HTTP/1.1 301 перемещен навсегда
Сервер: nginx
Дата: среда, 20 октября 2021 г., 08:14:13 по Гринвичу
Тип содержимого: текст/html
Длина содержимого: 162
Расположение: https://example.com/api/open_graph/article1.
Соединение: Keep-alive
Строгая транспортная безопасность: max-age=31536000
X-Content-Type-Options: nosniff
X-XSS-защита: 1; режим = блок
Параметры X-Frame: SAMEORIGIN
Это почти хорошо, за исключением того, что api facebook graph не обрабатывает перенаправления. (Кто знает почему?). Поэтому вместо перенаправления на /апи/open_graph/*
сервер должен напрямую подключаться к восходящему потоку и пересылать запрос.
Но я не знаю как? Наивным решением было бы:
# Используйте /api/open_graph в апстриме для внешних обращений в Facebook
если ($http_user_agent ~* "^facebookexternalhit.*$") {
переписать ^/(.*)$ /api/open_graph/$1 навсегда;
прокси_пароль http://www;
proxy_read_timeout 90;
proxy_redirect http://www https://example.com;
}
Но это не работает, потому что proxy_pass
можно использовать только внутри место расположения
. Его нельзя использовать внутри если
. Если я попробую эту конфигурацию, я получу:
nginx: [появление] директива proxy_pass не разрешена здесь, в /etc/nginx/sites-enabled/example-www:62
nginx: проверка файла конфигурации /etc/nginx/nginx.conf не удалась
Я мог бы изменить код программы в восходящем потоке (например, добавить туда фильтр для пользовательского агента), но это было бы довольно сложно.
Есть ли обходной путь для этого в nginx?
Этот вопрос связан с: nginx — proxy_pass на user_agent но у меня это тоже не сработало (выдало ошибку)