Как в Nginx добавить заголовки в определённом location (для ответа API)?

Исходные данные:
server {
    ... 
    location / {
        ...
    }
    location /api/v1/ {
        ...
    }
    location ~ "^(.+\.php)($|/)" {
        ...
    }
}

Объявим заголовок , например:
add_header 'X-my-api-header' 'bla-bla-bla';

Требуется добавить этот заголовок для генерируемого api json или xml в location /api/v1/ .

Если заголовок добавить до описания правил для location, заголовок появляется, но для всего ресурса. Если его добавить для location api или location /, заголовок отсутствует в ответе сервера, но появляется если поместить заголовок в location php. Тогда заголовок появляется во всех ответах запросов к php-скриптам.

Так как API отдаёт данные в запрашиваемых форматах, пытался объявить заголовок для этих форматов, но тщетно. Возможно это происходит потому что выдачу данных генерирует php-скрипт. До этой задачки наивно полагал что знаю как работают настройки location.
  • Вопрос задан
  • 9056 просмотров
Решения вопроса 1
@Nc_Soft
У вас одна точка входа у приложения?
Ответ написан
Пригласить эксперта
Ответы на вопрос 3
alekciy
@alekciy
Вёбных дел мастер
Мне кажется подход изначально архитектурно неправильный.

api json или xml

За данными как я понимаю все равно нужно ходить к PHP. Так зачем эти танцы с location? Отправляйте на обработку в php все запросы, скрипте по расширению файла добавлять соотвествующий http header.
Ответ написан
justabaka
@justabaka
Если 1 location, то можно if'ом, если нет опасений, что if is evil, как-то так:

if ($uri ~ ^/api/v1/.*){
add_header 'X-my-api-header' 'bla-bla-bla';
}

Если можно наплодить сколько угодно локейшенов, то копируем уже имеющийся в /api/v1/, настраиваем аналогично имеющемуся (fastcgi_pass и все такое) и добавляем заголовок.

А вообще, проще ставить заголовок силами PHP, чем заниматься таким извращением.
Ответ написан
ptchol
@ptchol
Linux system administrator
Вероятно в location /api/v1/ у вас прописано что то вроде
if (!-e $request_filename) {
rewrite ^.*$ /index.php last;
}

Поэтому запрос и уходит в location ~ "^(.+\.php)($|/)"
Если я правильно понимаю задачу, то вам нужно для ответов бэкенда с content-type json / xml проставлять соответсвующий хедер.
Здесь может помочь проверка хедера Content-type в ответе сервера.
Получить его можно через переменные upstream модуля: $upstream_http_$HEADER. Тоесть в вашем случае это будет выглядеть как $upstream_http_content_type.
А далее если вам нужно кастомное значение загловка для каждого типа контента, применить map, как то так:
map $upstream_http_content_type $type {
default "custom_header_default";
"application/json" "custom_header_json";
"text/xml" "custom_header_xml";
}


Сам такое ни разу не делал, поэтому отвечаю только "теоретически", как это может работать.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы