Нет ответа от Grafana через AJAX
У меня есть Grafana в контейнере Docker (grafana/grafana
изображение из репозитория Docker) с портом 3000, перенаправленным на мой локальный хост. мой docker-compose.yml
ниже:
version: '2.1'
services:
grafana:
image: grafana/grafana
ports:
- 3000:3000
Первоначально у меня также есть ссылка на Graphite и некоторые тома и конфигурации среды (GF_SECURITY_ADMIN_PASSWORD
только) но я полагаю, это не имеет значения.
Я могу получить ответ от Графана с помощью простого curl
вызов:
$ curl http://localhost:3000
<a href="/login">Found</a>.
Но когда я пытаюсь получить его с помощью вызова AJAX, это дает мне странный результат:
$.ajax({url: 'http://localhost:3000', beforeSend: function(xhr, settings) {alert('before setting header'); xhr.setRequestHeader('Access-Control-Allow-Origin', '*'); alert('after setting header');}});
[many JSON fields]
responseText:""
[many JSON fields]
statusText: "error"
[many JSON fields]
Оповещения говорят, что заголовок настроен на прием запросов от любого источника.
То же самое происходит (curl работает, но ajax нет), когда я вызываю адрес контейнера Docker напрямую.
Что происходит в фоновом режиме? Почему второй запрос не работает? Как я могу получить ответ от Grafana через звонок AJAX?
1 ответ
Проблема в том, что по умолчанию CORS не включен на графане. Запрос curl не проверяет CORS, но браузер делает. Это то, что защищает один сайт, чтобы называть API других сайтов.
Таким образом, ваше решение было бы поставить обратный прокси-сервер nginx перед Grafana. Ниже docker-compose.yml
для того же
version: '2.1'
services:
grafana:
image: grafana/grafana
nginx:
image: nginx
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
ports:
- "3000:80"
И ниже конфиг nginx добавит CORS к нему, но он очень открытый, позволит каждому доступ
events {
worker_connections 1024;
}
http {
#
# Acts as a nginx HTTPS proxy server
# enabling CORS only to domains matched by regex
# /https?://.*\.mckinsey\.com(:[0-9]+)?)/
#
# Based on:
# * http://blog.themillhousegroup.com/2013/05/nginx-as-cors-enabled-https-proxy.html
# * http://enable-cors.org/server_nginx.html
#
server {
listen 80;
location / {
#if ($http_origin ~* (https?://.*\.tarunlalwani\.com(:[0-9]+)?$)) {
# set $cors "1";
#}
set $cors "1";
# OPTIONS indicates a CORS pre-flight request
if ($request_method = 'OPTIONS') {
set $cors "${cors}o";
}
# Append CORS headers to any request from
# allowed CORS domain, except OPTIONS
if ($cors = "1") {
add_header Access-Control-Allow-Origin $http_origin always;
add_header Access-Control-Allow-Credentials true always;
proxy_pass http://grafana:3000;
}
# OPTIONS (pre-flight) request from allowed
# CORS domain. return response directly
if ($cors = "1o") {
add_header 'Access-Control-Allow-Origin' '$http_origin' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE' always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
add_header 'Access-Control-Allow-Headers' 'Origin,Content-Type,Accept' always;
add_header Content-Length 0;
add_header Content-Type text/plain;
return 204;
}
# Requests from non-allowed CORS domains
proxy_pass http://grafana:3000;
}
}
}
Также для теста вы не должны использовать
xhr.setRequestHeader('Access-Control-Allow-Origin', '*');
Удалите это и проверьте, и это должно работать