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

Kotlin JS Karma测试无法发起HTTP请求问题排查

用Karma运行Kotlin/JS测试时无法发起HTTP请求的问题解决

问题

在使用Karma运行Kotlin/JS测试时,无论是通过Ktor Client还是直接调用window.fetch发起HTTP请求,都报错TypeError: Failed to fetch,无法成功请求外部接口。

相关配置与代码

Gradle配置(build.gradle.kts)

js(IR) {
    useCommonJs()
    browser {
        testTask {
            useKarma {
                useChromeHeadless()
            }
        }
    }
    binaries.executable()
}

Ktor Client请求代码

val text = HttpClient(Js).get("https://www.google.com/") {
    header("Content-Type", "text/html; charset=utf-8")
    header("Accept", "*/*")
}.body<String>()

对应错误日志

> Task :jsTestClasses
> Task :compileTestDevelopmentExecutableKotlinJs
> Task :jsTestTestDevelopmentExecutableCompileSync
> Task :jsBrowserTest
myTest before fetch
TRACE: Adding Accept-Charset=UTF-8 to https://www.google.com/TRACE: Processing exception Error_0: Fail to fetch for request https://www.google.com/Error_0: Fail to fetch
    at http://localhost:9876/absolute/var/folders/cb/nd4gn6pn79zg52rz_l5bl1bdjfnmjy/T/_karma_webpack_293805/commons.js?58a2b80ce49dc5767b060dfe37192606438b082a:52793:26
Caused by: TypeError: Failed to fetch
    at commonFetch (http://localhost:9876/absolute/var/folders/cb/nd4gn6pn79zg52rz_l5bl1bdjfnmjy/T/_karma_webpack_293805/commons.js?58a2b80ce49dc5767b060dfe37192606438b082a:52730:13)
    at $executeCOROUTINE$16.doResume_5yljmg_k$ (http://localhost:9876/absolute/var/folders/cb/nd4gn6pn79zg52rz_l5bl1bdjfnmjy/T/_karma_webpack_293805/commons.js?58a2b80ce49dc5767b060dfe37192606438b082a:52105:29)
    at JsClientEngine.execute_95skru_k$ (http://localhost:9876/absolute/var/folders/cb/nd4gn6pn79zg52rz_l5bl1bdjfnmjy/T/_karma_webpack_293805/commons.js?58a2b80ce49dc5767b060dfe37192606438b082a:52224:16)
    at HttpClientEngine$executeWithinCallContext$slambda.doResume_5yljmg_k$ (http://localhost:9876/absolute/var/folders/cb/nd4gn6pn79zg52rz_l5bl1bdjfnmjy/T/_karma_webpack_293805/commons.js?58a2b80ce49dc5767b060dfe37192606438b082a:46100:44)
    at HttpClientEngine$executeWithinCallContext$slambda.invoke_1yhb3o_k$ (http://localhost:9876/absolute/var/folders/cb/nd4gn6pn79zg52rz_l5bl1bdjfnmjy/T/_karma_webpack_293805/commons.js?58a2b80ce49dc5767b060dfe37192606438b082a:46082:16)
    at l (http://localhost:9876/absolute/var/folders/cb/nd4gn6pn79zg52rz_l5bl1bdjfnmjy/T/_karma_webpack_293805/commons.js?58a2b80ce49dc5767b060dfe37192606438b082a:46133:16)
    at _no_name_provided__qut3iv_6.doResume_5yljmg_k$ (http://localhost:9876/absolute/var/folders/cb/nd4gn6pn79zg52rz_l5bl1bdjfnmjy/T/_karma_webpack_293805/commons.js?58a2b80ce49dc5767b060dfe37192606438b082a:31198:43)
    at CoroutineImpl.resumeWith_7onugl_k$ (http://localhost:9876/absolute/var/folders/cb/nd4gn6pn79zg52rz_l5bl1bdjfnmjy/T/_karma_webpack_293805/commons.js?58a2b80ce49dc5767b060dfe37192606438b082a:31062:33)
    at CoroutineImpl.resumeWith_s3a3yh_k$ (http://localhost:9876/absolute/var/folders/cb/nd4gn6pn79zg52rz_l5bl1bdjfnmjy/T/_karma_webpack_293805/commons.js?58a2b80ce49dc5767b060dfe37192606438b082a:31108:17)
    at DispatchedTask.run_mw4iiu_k$ (http://localhost:9876/absolute/var/folders/cb/nd4gn6pn79zg52rz_l5bl1bdjfnmjy/T/_karma_webpack_293805/commons.js?58a2b80ce49dc5767b060dfe37192606438b082a:41652:24)

尝试window.fetch的代码

val response = window.fetch(url).await()
println("response: ${response.body}")

对应错误日志

> Task :jsTestTestDevelopmentExecutableCompileSync
> Task :jsBrowserTest
getFileText before fetch
TypeError: Failed to fetch
TypeError: Failed to fetch
    at 2.doResume_5yljmg(/var/folders/cb/nd4gn6pn79zg52rz_l5bl1bdjfnmjy/T/_karma_webpack_124481/commons.js:3883)
    at <global>.httpGet(/var/folders/cb/nd4gn6pn79zg52rz_l5bl1bdjfnmjy/T/_karma_webpack_124481/commons.js:3765)
    at 1.doResume_5yljmg(/var/folders/cb/nd4gn6pn79zg52rz_l5bl1bdjfnmjy/T/_karma_webpack_124481/commons.js:3845)
    at HtmlResourceLoader.getFileText_6u54xq(/var/folders/cb/nd4gn6pn79zg52rz_l5bl1bdjfnmjy/T/_karma_webpack_124481/commons.js:3920)
    at slambda.doResume_5yljmg(/var/folders/cb/nd4gn6pn79zg52rz_l5bl1bdjfnmjy/T/_karma_webpack_124481/commons.js:992)
    at slambda.invoke_pbb09x(/var/folders/cb/nd4gn6pn79zg52rz_l5bl1bdjfnmjy/T/_karma_webpack_124481/commons.js:978)
    at slambda.$block(/var/folders/cb/nd4gn6pn79zg52rz_l5bl1bdjfnmjy/T/_karma_webpack_124481/commons.js:1023)
    at slambda.doResume_5yljmg(/var/folders/cb/nd4gn6pn79zg52rz_l5bl1bdjfnmjy/T/_karma_webpack_124481/commons.js:3792)
    at slambda.invoke_d6gbsu(/var/folders/cb/nd4gn6pn79zg52rz_l5bl1bdjfnmjy/T/_karma_webpack_124481/commons.js:3778)
    at <global>.l(/var/folders/cb/nd4gn6pn79zg52rz_l5bl1bdjfnmjy/T/_karma_webpack_124481/commons.js:3825)

解决方法

方法1:修改Chrome Headless启动参数

问题根源是Chrome Headless默认启用Web安全策略,限制了跨域请求。修改Karma配置,添加禁用Web安全的参数:

js(IR) {
    useCommonJs()
    browser {
        testTask {
            useKarma {
                useChromeHeadless {
                    args("--disable-web-security", "--disable-features=VizDisplayCompositor")
                }
            }
        }
    }
    binaries.executable()
}

方法2:改用Mock数据(推荐)

单元测试应避免依赖外部服务,可通过Mock模拟HTTP请求的返回结果,比如使用Ktor的MockEngine:

val client = HttpClient(MockEngine) {
    engine {
        addHandler { request ->
            respondText("Mocked response content", status = HttpStatusCode.OK)
        }
    }
}

方法3:配置Karma代理

如果必须发起真实请求,可在Karma中配置代理,将请求转发到目标服务器,避免跨域问题:

useKarma {
    proxies = mapOf(
        "/api" to "https://www.google.com"
    )
}

然后测试代码中请求/api即可,Karma会自动转发到目标地址。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 15:40:38