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

JavaScript调用ClickHouse遇ERR_EMPTY_RESPONSE及CORS问题求助

解决Chrome中JS请求ClickHouse的CORS及认证问题

问题核心原因

  1. 内网仍会触发浏览器CORS检查:只要是浏览器环境(Chrome),跨源请求(即使是内网不同服务)都会执行CORS策略,和是否在企业内网无关。
  2. 错误的请求头设置:你代码里的Access-Control-Allow-Origins是响应头,只能由服务器返回,放在请求头里不仅无效,还会让浏览器认为这是非简单请求,触发OPTIONS预检请求。而ClickHouse默认没处理OPTIONS请求,直接返回空响应,导致ERR_EMPTY_RESPONSE。
  3. no-cors模式的限制:开启这个模式后,浏览器会强制屏蔽所有自定义请求头(包括Authorization),所以服务器收不到你的认证信息,返回403。

无需修改ClickHouse的解决方案

方案1:调整请求头,避免触发预检请求

ClickHouse的GET查询不需要Content-Type: application/json,Postman能成功大概率是没加这个头。把这个不必要的请求头去掉,让请求变成浏览器认可的简单请求,就不会触发预检:

async function getDataFromClickHouse () {
    const _baseUrl = 'http://servername:8123/';
    const _username = 'login';
    const _password = 'password';
    const _query = 'SELECT * FROM any_table';

    const base64Credentials = btoa(`${_username}:${_password}`);
    const url = `${_baseUrl}/?query=${encodeURIComponent(_query)}`;

    try {
        const response = await fetch(url, {
            method: 'GET',
            headers: {
                'Authorization': `Basic ${base64Credentials}`
                // 去掉Content-Type和无效的Access-Control-Allow-Origins
            }
        });
        if (response.ok) {
            // 注意:ClickHouse默认返回TSV格式,不是JSON,直接用response.json()会报错
            // 改成获取文本后自行解析,或者在查询里指定FORMAT JSON
            const rawData = await response.text();
            // 如果要JSON格式,修改_query为'SELECT * FROM any_table FORMAT JSON'
            return rawData;
        } else {
            throw new Error(`Error executing ClickHouse query: ${response.statusText}`);
        }
    } catch (error) {
        console.error(error);
    }
}

补充:ClickHouse的GET请求默认返回TSV(制表符分隔)格式,如果你要JSON,记得在查询末尾加FORMAT JSON,这样才能用response.json()解析。

方案2:用Nginx做反向代理(生产环境推荐)

在前端和ClickHouse之间加一层Nginx代理,由Nginx处理CORS并转发请求,完全不用修改ClickHouse配置:

server {
    listen 8080;
    server_name localhost;

    location /clickhouse/ {
        # 转发请求到ClickHouse
        proxy_pass http://servername:8123/;
        proxy_set_header Authorization $http_authorization;

        # 添加CORS响应头
        add_header Access-Control-Allow-Origin *;
        add_header Access-Control-Allow-Methods GET,OPTIONS;
        add_header Access-Control-Allow-Headers Authorization;

        # 处理OPTIONS预检请求
        if ($request_method = OPTIONS) {
            return 204;
        }
    }
}

然后前端请求地址改成http://localhost:8080/clickhouse/?query=...,这样浏览器的跨源请求就会被Nginx的CORS头允许。

方案3:开发环境临时关闭Chrome的CORS检查

只适合本地开发测试,生产环境不能用:

  • Windows:在命令行执行chrome.exe --disable-web-security --user-data-dir="C:/ChromeDevSession"
  • macOS:执行open -n -a "Google Chrome" --args --disable-web-security --user-data-dir="/tmp/ChromeDevSession"
  • Linux:执行google-chrome --disable-web-security --user-data-dir="/tmp/ChromeDevSession"

注意:这个会关闭Chrome的所有安全检查,不要用这个窗口浏览其他网站,仅限开发测试。

内容的提问来源于stack exchange,提问作者Артём Пучков

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 07:40:20