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

使用node-fetch的blobFrom等函数读取本地文件时出现无效URL错误

问题:node-fetch读取本地文件为Blob时触发无效URL错误

尝试使用node-fetch库将本地文件读取为Blob,但每次操作都会触发Invalid URL错误。

代码示例:

const express = require('express');
const cors = require('cors');
const bodyParser = require("body-parser");

const fetch = (...args) =>
  import('node-fetch').then(({ default: fetch }) => fetch(...args));

const blobFromSync = (...args) =>
  import('node-fetch').then(({ blobFromSync }) => fetch(...args));

const blobFrom = (...args) =>
  import('node-fetch').then(({ blobFrom }) => fetch(...args));

const fileFrom = (...args) =>
  import('node-fetch').then(({ fileFrom }) => fetch(...args));

const app = express();
const port = 3000;

// 配置express使用body-parser中间件
app.use(cors())
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());

app.use(function (req, res, next) {
    res.header("Access-Control-Allow-Origin", "*")
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept")
    next()
});

app.get('/recorded', async (req, res) => {
    try {
        let file_location = './path/to/video.mp4';
        const file = fileFrom(file_location);

        const chunkSize = 40000
        for (let start = 0; start < file.size; start += chunkSize) {
            const chunk = file.slice(start, start + chunkSize + 1)
            // 后续会执行fetch请求
            // await fetch(url, { method: 'post', body: chunk, headers: headers, }).then(res => res.text())
        }

        res.status(200);
        res.send().end();
    } catch (e) {
        console.log(e);
    }
});

app.listen(port, () => {
    console.log(`Example app listening on port ${port}`)
});

错误信息(无法被try/catch捕获):

TypeError [ERR_INVALID_URL]: Invalid URL
    at new NodeError (node:internal/errors:377:5)
    at URL.onParseError (node:internal/url:563:9)
    at new URL (node:internal/url:643:5)
    at new Request (file:///Users/xxxxxx/Development/terminal-backend/node_modules/node-fetch/src/request.js:55:16)
    at file:///Users/xxxx/Development/terminal-backend/node_modules/node-fetch/src/index.js:51:19
    at new Promise (<anonymous>)
    at fetch (file:///Users/xxxx/Development/terminal-backend/node_modules/node-fetch/src/index.js:49:9)
    at /Users/xxxxx/Development/terminal-backend/src/server.js:11:53 {
  input: './path/to/video.mp4',
  code: 'ERR_INVALID_URL'
}

使用blobFromSync和blobFrom也会抛出相同错误,明明是本地文件,为何会出现无效URL错误?


解答

错误核心:方法封装逻辑错误

你在封装blobFromSync、blobFrom、fileFrom这些node-fetch提供的本地文件处理方法时,犯了关键错误——从import拿到对应方法后,调用的却是fetch而非目标方法。以fileFrom为例:

const fileFrom = (...args) =>
  import('node-fetch').then(({ fileFrom }) => fetch(...args));

这里最终调用的是fetch(args),但fetch是用来发送HTTP请求的工具,它会把你传入的本地路径当成URL解析,自然触发ERR_INVALID_URL错误。

修正方法封装

将每个方法里的fetch替换为对应的目标方法:

const fetch = (...args) =>
  import('node-fetch').then(({ default: fetch }) => fetch(...args));

const blobFromSync = (...args) =>
  import('node-fetch').then(({ blobFromSync }) => blobFromSync(...args));

const blobFrom = (...args) =>
  import('node-fetch').then(({ blobFrom }) => blobFrom(...args));

const fileFrom = (...args) =>
  import('node-fetch').then(({ fileFrom }) => fileFrom(...args));

其他需修正的问题

  1. 异步处理缺失:fileFrom是异步方法,返回Promise,原代码直接访问file.size会报错,需用await等待Promise完成:
const file = await fileFrom(file_location);
  1. 错误捕获失效:之前错误无法被try/catch捕获,是因为fileFrom的Promise未被await,异步错误冒泡到全局。加上await后,错误会被正常捕获。

修正后的接口代码

app.get('/recorded', async (req, res) => {
    try {
        let file_location = './path/to/video.mp4';
        // 等待fileFrom异步执行完成
        const file = await fileFrom(file_location);

        const chunkSize = 40000
        // 循环时确保end不超过文件大小
        for (let start = 0; start < file.size; start += chunkSize) {
            const end = Math.min(start + chunkSize, file.size);
            const chunk = file.slice(start, end);
            // 执行fetch请求时记得添加await
            // await fetch(url, { method: 'post', body: chunk, headers: headers });
        }

        res.status(200).send('处理完成').end();
    } catch (e) {
        console.error('处理出错:', e);
        res.status(500).send('内部错误').end();
    }
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 17:39:53