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

MV3扩展Service Worker中Axios报adapter is not a function错误

问题产生原因

Manifest V3 规范下扩展的后台运行在 Service Worker 上下文,这个环境既不存在浏览器环境的XMLHttpRequest对象,也不存在 Node.js 环境的http/https内置模块。
Axios 默认自带两个请求适配器:

  • 浏览器端用的xhr适配器,依赖XMLHttpRequest实现
  • Node.js 端用的http适配器,依赖 Node 原生http模块
    Axios 初始化时会自动检测当前运行环境选择可用适配器,在 Service Worker 环境下两个默认适配器都无法运行,自动检测匹配失败,就会抛出TypeError: adapter is not a function错误。

现有配置还存在两个隐含问题:

  • 代码中使用了storage.local读写配置,但manifest.json的permissions里没有声明storage权限,后续读写缓存会报错
  • Manifest V3 中后台脚本发起跨域请求需要声明host_permissions,当前配置没有加对应权限,适配器修复后请求也会被浏览器拦截。

把请求从 content script 转发到后台的思路是正确的:content script 运行在目标页面的上下文,受页面同源策略限制才会触发 CORS 错误,后台 Service Worker 属于扩展独立上下文,本身不受站点 CORS 规则限制,只要声明对应 host 权限就可以正常发起跨域请求。

修复步骤

1. 补全manifest必要权限

修改manifest.json,补全缺失的权限配置:

{
    "manifest_version": 3,
    "name": "Teamlock web extension",
    "description": "Teamlock web extension",
    "version": "0.0.1",
    "background": {
        "service_worker": "/background.js"
    },
    "action": {
        "default_popup": "popup.html"
    },
    "content_scripts": [
        {
            "matches": [
                "<all_urls>"
            ],
            "js": [
                "/content.js"
            ]
        }
    ],
    "permissions": [
        "tabs",
        "storage"
    ],
    "host_permissions": [
        "<all_urls>"
        // 遵循最小权限原则的话,可以替换为实际接口域名,例如 "https://api.your-teamlock-domain.com/*"
    ]
}

2. 给Axios显式指定Service Worker可用的适配器

Service Worker 原生支持fetch API,安装对应的fetch适配器给Axios使用即可:

  • 首先安装依赖包:
npm install @vespaiach/axios-fetch-adapter
  • 修改封装的http模块,创建实例时显式指定适配器:
import axios from "axios"
import fetchAdapter from "@vespaiach/axios-fetch-adapter"
import { storage } from "webextension-polyfill";

const service = axios.create({
    adapter: fetchAdapter
})

// 原有请求拦截器逻辑保持不变
service.interceptors.request.use(
    async (config) => {
        const {token} = await storage.local.get("token")
        if (token) {
            config.headers["Authorization"] = `Bearer ${token}`
        }
        const {instance} = await storage.local.get("instance") 
        config.baseURL = instance;
        return config
    },
    (error) => {
        console.log(error)
        return Promise.reject(error)
    }
)
export default service

3. 修正后台消息监听逻辑

首先补全http模块的导入,另外注意扩展消息传递只能序列化普通对象,Axios返回的响应实例包含大量不可序列化的属性,需要手动提取有效字段再返回,避免消息传递报错:

import {runtime} from "webextension-polyfill";
import http from "./path/to/your/http-module"; // 替换成http模块的实际路径
runtime.onMessage.addListener(async (request,sender) =>{
    console.log("bien reçu");
    const res = await http.get(`/api/v1/workspace`)
    // 仅返回可序列化的必要字段
    return {
        data: res.data,
        status: res.status,
        headers: res.headers
    }
})

如果不想额外引入适配器依赖,也可以直接在后台Service Worker中用原生fetch封装请求逻辑,不需要依赖Axios,适合请求逻辑简单的场景。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 16:51:26