You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript fetch调用Grafana Loki Cloud接口遇权限及CORS问题求助

解决Grafana Loki Cloud前端查询的两类问题

问题场景

我尝试从Grafana Loki Cloud查询数据,以下curl命令可正常运行:

curl -s -G "https://<user>:<API key>@<site>.grafana.net/loki/api/v1/query_range" --data-urlencode 'query={job="maplejob"}'

凭证置于链接中的报错

改写为JavaScript代码后出现报错:

const query_url = new URL('https://<user>:<API key>@<site>.grafana.net/loki/api/v1/query_range');
const params = new URLSearchParams(query_url.search);
params.set('query', '{job="maplejob"}');
query_url.search = params;

fetch(query_url.toString(), {})
    .then((response) => { console.log(response) })
    .catch(console.error);

错误信息:

TypeError: Failed to execute 'fetch' on 'Window': Request cannot be constructed from a URL that includes credentials

凭证置于请求头中的报错

调整为将凭证放在请求头后,仍出现CORS相关报错:

const query_url = new URL('https://<site>.grafana.net/loki/api/v1/query_range');
const params = new URLSearchParams(query_url.search);
params.set('query', '{job="maplejob"}');
query_url.search = params;

fetch(query_url.toString(), {
    headers: {
        'Authorization': `Basic ${btoa('<user>:<API key>')}`
    },
})
    .then((response) => { console.log(response) })
    .catch(console.error);

错误信息:

Access to fetch at '' from origin '' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.


解决方法

1. 后端代理(推荐方案)

浏览器的CORS限制是安全机制,无法直接绕过,最可靠的方式是通过自己的后端服务转发请求:

  • 前端向自己的后端发送查询请求,不直接调用Loki Cloud API
  • 后端使用服务器端请求(不受浏览器CORS限制)调用Loki Cloud,携带凭证完成查询
  • 后端将Loki返回的数据转发给前端

示例Node.js后端(Express框架):

const express = require('express');
const axios = require('axios');
const app = express();
const port = 3000;

// 配置跨域允许(或使用cors中间件)
app.use((req, res, next) => {
  res.header('Access-Control-Allow-Origin', '<你的前端域名>');
  res.header('Access-Control-Allow-Methods', 'GET, OPTIONS');
  res.header('Access-Control-Allow-Headers', 'Content-Type');
  next();
});

// 封装Loki查询接口
app.get('/api/loki-query', async (req, res) => {
  try {
    const query = req.query.query;
    const lokiUrl = new URL('https://<site>.grafana.net/loki/api/v1/query_range');
    lokiUrl.searchParams.set('query', query);

    // 发起服务器端请求,携带Loki凭证
    const response = await axios.get(lokiUrl.toString(), {
      auth: {
        username: '<user>',
        password: '<API key>'
      }
    });

    res.json(response.data);
  } catch (error) {
    res.status(error.response?.status || 500).json({ 
      error: error.message || '查询失败' 
    });
  }
});

app.listen(port, () => {
  console.log(`代理服务运行在端口 ${port}`);
});

前端调用代码:

fetch('http://你的后端域名:3000/api/loki-query?query={job="maplejob"}')
  .then(res => res.json())
  .then(data => console.log(data))
  .catch(console.error);

2. 检查Grafana Cloud CORS配置(可选)

登录Grafana Cloud控制台,查看是否支持将你的前端域名添加到CORS白名单。但注意Loki Cloud的公开API通常默认不开放自定义CORS配置,此方案不一定可行。

关于URL带凭证报错的说明

浏览器的fetch API出于安全考虑,禁止直接使用包含用户名和密码的URL发起请求,因此第一种写法必然报错,必须改用后端代理或Authorization头(但Authorization头会触发CORS预检,仍需后端配合)。


内容的提问来源于stack exchange,提问作者user22009348

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 07:47:33