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

Node.js连接Google Cloud Storage报错:TypeError异常求助

问题原因分析

你遇到的错误核心在于代码混用了Node.js服务端库和浏览器DOM API:

  • @google-cloud/storage 是专门给Node.js服务端设计的库,依赖Node.js的运行环境(比如fs模块、服务端网络请求逻辑),无法直接在浏览器环境中运行。
  • 代码里的document.getElementById、element.onclick是浏览器端的DOM操作API,这会导致代码要么在Node.js环境跑时找不到document,要么在浏览器环境跑时,@google-cloud/storage内部逻辑因为环境不兼容(比如fetch的signal参数处理、缺少Node.js核心模块)抛出错误。
解决方法

根据你的使用场景,分两种情况处理:

情况1:后端(Node.js服务端)执行上传

如果是要在Node.js服务端完成上传,直接移除浏览器相关代码,改成纯服务端逻辑:

const { Storage } = require('@google-cloud/storage');
const fs = require('fs');

const bucketName = 'gcloudconnection.json';
const GOOGLE_CLOUD_PROJECT_ID = 'xxxxx';

// 初始化Storage客户端
const gc = new Storage({
    projectId: GOOGLE_CLOUD_PROJECT_ID,
    keyFilename: bucketName
});

// 定义上传函数
async function uploadFile() {
    const bucket = gc.bucket('lawflow');
    const file = bucket.file('testtrial');

    fs.createReadStream('/path/to/your/local/file')
      .pipe(file.createWriteStream())
      .on('error', (err) => {
          console.error('上传出错:', err);
      })
      .on('finish', () => {
          console.log('文件上传完成');
      });
}

// 执行上传
uploadFile();

运行方式:直接用Node.js执行这个脚本,确保服务端环境已安装依赖(npm install @google-cloud/storage),且密钥文件路径正确。

情况2:前端(浏览器)直接上传到GCS

如果要在浏览器里触发上传,不能用@google-cloud/storage,推荐用预签名URL的方式:

  1. 先在Node.js服务端生成一个允许前端上传的预签名URL
  2. 前端用这个URL,通过普通的fetch或者表单提交完成上传

服务端生成预签名URL的示例:

const { Storage } = require('@google-cloud/storage');

const gc = new Storage({
    projectId: 'xxxxx',
    keyFilename: 'gcloudconnection.json'
});

async function generateUploadUrl() {
    const bucket = gc.bucket('lawflow');
    const file = bucket.file('testtrial');

    // 生成有效期为1小时的预签名URL
    const [url] = await file.getSignedUrl({
        action: 'write',
        expires: Date.now() + 3600 * 1000,
        contentType: 'application/octet-stream' // 根据你的文件类型调整
    });

    console.log('前端上传URL:', url);
    return url;
}

generateUploadUrl();

前端使用预签名URL上传的示例:

<button id="log-in">选择文件上传</button>
<input type="file" id="file-input" style="display:none;">

<script>
const uploadBtn = document.getElementById('log-in');
const fileInput = document.getElementById('file-input');

uploadBtn.onclick = () => {
    fileInput.click();
};

fileInput.onchange = async (e) => {
    const file = e.target.files[0];
    if (!file) return;

    // 这里替换成服务端生成的预签名URL
    const uploadUrl = '从服务端获取的预签名URL';

    try {
        const response = await fetch(uploadUrl, {
            method: 'PUT',
            body: file,
            headers: {
                'Content-Type': file.type
            }
        });

        if (response.ok) {
            console.log('文件上传成功');
        } else {
            console.error('上传失败:', response.statusText);
        }
    } catch (err) {
        console.error('上传出错:', err);
    }
};
</script>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 09:15:36