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

保存本地文件时出现createObjectURL执行错误,求问题排查

解决TypeError: Failed to execute 'createObjectURL' on 'URL'问题

你遇到的这个错误通常是因为传给createObjectURL的参数不是有效的Blob对象,结合你的代码来看,主要有以下几个问题和修复方案:

1. 后端文件名解码错误

前端通过encodeURIComponent(fileName)编码了文件名,但后端直接用编码后的字符串去查找文件,这会导致找不到目标文件(实际文件名是未编码的原始名称),最终返回404或无效内容,前端拿到的Blob对象无效,触发错误。

修复后端代码:
在接收fileName参数后,先进行URL解码:

public HttpResponseMessage Open(int savInitId, string fileName)
{
    // 解码前端传来的文件名
    fileName = HttpUtility.UrlDecode(fileName);
    var fullPath = CommonService.ServerSharedDrivePath + savInitId.ToString();
    DirectoryInfo di = new DirectoryInfo(fullPath);
    FileInfo[] files = di.GetFiles(fileName);

    if (files.Length > 0)
    {
        HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);
        try
        {
            var fileStream = files[0].Open(FileMode.Open, FileAccess.Read);
            response.Content = new StreamContent(fileStream);
            response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
            response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") { FileName = fileName };
            return response;
        }
        catch (Exception ex)
        {
            // 处理文件打开失败的情况,比如文件被占用
            return new HttpResponseMessage(HttpStatusCode.InternalServerError);
        }
    }
    return new HttpResponseMessage(HttpStatusCode.NotFound);
}

2. 前端增加Blob有效性校验

在调用createObjectURL前,先确认拿到的blob是有效的Blob对象,避免传入null/undefined或非Blob类型的值:

修复前端代码:

function openFile() {
    var fileName = $(this).closest(".file-box").find(".file-name").text();
    var encodedFileName = encodeURIComponent(fileName);
    $(document.body).showLoaderWithText("Downloading File");
    $.ajax({
        url: "/Procurement/Open",
        method: "POST",
        data: JSON.stringify({ savInitId: mv.options.savInitId, fileName: encodedFileName }),
        contentType: "application/json", // 新增:指定请求内容类型为JSON
        xhrFields: {
            responseType: "blob"
        },
        global: false,
        success: function (blob) {
            // 校验Blob有效性
            if (!(blob instanceof Blob) || blob.size === 0) {
                $(document.body).resetLoader();
                alert("下载失败:获取到无效文件内容");
                return;
            }

            if (window.navigator && window.navigator.msSaveOrOpenBlob) {
                window.navigator.msSaveOrOpenBlob(blob, fileName);
            } else {
                var a = document.createElement("a");
                var url = window.URL.createObjectURL(blob);
                a.href = url;
                a.download = fileName;
                // 解决部分浏览器无法直接触发click的问题
                document.body.appendChild(a);
                a.click();
                document.body.removeChild(a);
                window.URL.revokeObjectURL(url);
            }
            $(document.body).resetLoader();
        },
        error: function (jqXhr, ajaxSettings, thrownError) {
            $(document.body).resetLoader();
            if (/^not found$/ig.test(thrownError)) {
                alert("文件不存在");
            } else {
                alert("下载失败:" + thrownError);
            }
        },
        complete: function () {
            // 这里的resetLoader可以移到success和error里,避免重复执行
        }
    });
}

额外优化点

  • 前端AJAX请求新增contentType: "application/json",确保后端能正确解析JSON格式的请求体;
  • 前端创建a标签后先添加到DOM再触发click,避免部分浏览器(如Firefox)无法触发下载;
  • 后端增加文件打开异常捕获,避免因文件被占用等情况导致返回无效响应;
  • 前端error回调添加用户提示,方便排查问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 21:47:38