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

Next.js 15.1.7中调用依赖@basisai/remote-zip的Server Action时出现XMLHttpRequest未定义错误

Next.js 15.1.7中调用依赖@basisai/remote-zip的Server Action时出现XMLHttpRequest未定义错误

问题场景

我在Next.js项目中通过Server Action调用@basisai/remote-zip库读取远程ZIP文件内容时遇到了服务器端错误。具体代码结构如下:

前端客户端组件

'use client';

import Image from "next/image";
import { doSomething } from "./serveractions/do-something";

export default function Home() {
  const handleClick = async () => {
    await doSomething()
  }

  return (
    <div className="grid grid-rows-[20px_1fr_20px] items-center justify-items-center min-h-screen p-8 pb-20 gap-16 sm:p-20 font-[family-name:var(--font-geist-sans)]">
      <button onClick={handleClick}>Press me</button>
      {/* 其余组件代码 */}
    </div>
  );
}

Server Action 代码

'use server';

import { RemoteZipPointer } from "@basisai/remote-zip";

export const doSomething = async() => {
    const url = new URL("https://github.com/unidoc/unipdf/archive/refs/tags/v3.66.0.zip");
    const remoteZip = await new RemoteZipPointer({ url }).populate();
    const files = remoteZip.files(); 

    files.forEach(file => console.log(file.filename));
}

点击按钮后触发服务器端错误,提示XMLHttpRequest is not defined,但相同代码在纯Node.js(Bun)环境下可以正常运行。我尝试过替换全局XMLHttpRequest为xmlhttprequest、xhr2或node-fetch,但均抛出TypeError: i.arrayBuffer is not a function的新错误。


问题原因

@basisai/remote-zip库底层依赖浏览器环境的XMLHttpRequest API,但Next.js的Server Action运行在Node.js服务器环境中,Node.js本身并没有内置这个浏览器专属的API,这就导致了未定义的错误。而你之前尝试的替换方案,其提供的XMLHttpRequest实现不完整,缺少库所需的arrayBuffer等标准方法,因此引发了新的类型错误。


解决方案

我们可以通过为Node.js环境提供完全符合标准的XMLHttpRequest实现,或者适配库的请求逻辑来解决这个问题,以下是两种可行方案:

方案1:使用undici提供兼容的XMLHttpRequest(推荐)

undici是Node.js官方推荐的高性能HTTP客户端,它提供了与浏览器标准完全对齐的XMLHttpRequest实现,完美支持arrayBuffer等方法。

  1. 首先安装依赖:
npm install undici
# 或使用 yarn add undici / pnpm add undici
  1. 在Server Action代码顶部注入全局兼容实现:
'use server';

// 为Node.js环境注入标准兼容的XMLHttpRequest
import { XMLHttpRequest } from 'undici';
globalThis.XMLHttpRequest = XMLHttpRequest;

import { RemoteZipPointer } from "@basisai/remote-zip";

export const doSomething = async() => {
    const url = new URL("https://github.com/unidoc/unipdf/archive/refs/tags/v3.66.0.zip");
    const remoteZip = await new RemoteZipPointer({ url }).populate();
    const files = remoteZip.files(); 

    files.forEach(file => console.log(file.filename));
}

方案2:自定义请求适配器(需库支持)

如果@basisai/remote-zip文档中提到允许自定义请求逻辑,可以直接用Node.js 18+内置的fetch API替代默认的XMLHttpRequest:

注意:该方案仅当库开放了自定义请求器的配置项时可用,若库未提供此能力则无法使用。

'use server';

import { RemoteZipPointer } from "@basisai/remote-zip";

export const doSomething = async() => {
    const url = new URL("https://github.com/unidoc/unipdf/archive/refs/tags/v3.66.0.zip");
    
    // 假设库支持通过request参数自定义请求逻辑
    const remoteZip = await new RemoteZipPointer({ 
        url,
        request: async (reqConfig) => {
            const response = await fetch(url, {
                method: reqConfig.method || 'GET',
                headers: reqConfig.headers,
            });
            // 返回库所需的响应结构
            return {
                arrayBuffer: () => response.arrayBuffer(),
                status: response.status,
                getResponseHeader: (name) => response.headers.get(name)
            };
        }
    }).populate();
    
    const files = remoteZip.files(); 
    files.forEach(file => console.log(file.filename));
}

验证

修改完成后重启Next.js项目,点击按钮即可正常读取远程ZIP文件的文件列表,不会再出现XMLHttpRequest is not defined的错误。

备注:内容来源于stack exchange,提问作者Dima Vavilov

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 11:13:01