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

Safari浏览器中如何将File对象赋值给type=file类型的input元素

解决方案

你遇到的问题来自两个层面:代码本身的参数错误,以及Safari对input[type=file]的files属性赋值的安全限制,下面给出具体修复方案:

一、先修复现有代码的基础错误

现有代码的几个错误会直接导致功能在所有浏览器都可能出现异常,优先修复:

    1. 修正文件类型返回值,openFile函数需要返回完整MIME类型而非后缀名,供canvas.toBlob使用:
    function openFile(file) {
        var extension = file.substr( (file.lastIndexOf('.') +1) ).toLowerCase();
        switch(extension) {
            case 'jpg':
            case 'jpeg':
                return 'image/jpeg'
            case 'png':
                return 'image/png' 
            default:
                return '1'
        }
    };
    
    1. 修正File对象创建时的type参数:
    // 原来的错误写法:type写死为"mime/type"
    // let file2 = new File([blob], new_file_name, {type:"mime/type", lastModified:new Date().getTime()});
    // 修正后:用实际的MIME类型
    let file2 = new File([blob], new_file_name, {type: MIME_TYPE, lastModified:new Date().getTime()});
    
    1. 补充QUALITY的默认值,避免超出大小限制场景下参数异常:
    var QUALITY = 0.9; // 先给默认值
    if (FileSize >= 8000000) {
        // 原有报错逻辑不变
    }
    

二、解决Safari下无法给input赋值的问题

这里给两种可选方案,优先选第一种,兼容性最好:

方案1:绕开input赋值,直接用FormData提交(推荐)

浏览器限制input的files属性赋值本质是安全策略,你完全不需要第二个隐藏的input存压缩后的文件,直接全局存储压缩后的File对象,提交时塞进FormData即可,兼容所有浏览器,后端逻辑无需修改:

  1. 先定义全局变量存压缩后的文件
// 放在脚本顶部
let compressedImageFile = null;
  1. 压缩生成file2后,不要赋值input,直接存到全局变量
// 替换原有给bt_current_file赋值的逻辑
compressedImageFile = file2;
  1. 表单提交时,把压缩后的文件塞入FormData
function submitUploadForm() {
    const form = document.getElementById('你的表单ID');
    const formData = new FormData(form);
    // 删除原input上传的未压缩文件,替换为压缩后的文件
    formData.delete('file_dep');
    formData.append('file_dep', compressedImageFile);
    // 用fetch/axios提交formData即可,后续上传到GCS的逻辑完全不变
    fetch('/你的上传接口地址', {
        method: 'POST',
        body: formData
    }).then(res => res.json()).then(result => {
        // 处理上传结果
    })
}

方案2:兼容Safari的input赋值写法

如果你一定要保留给input赋值的逻辑,可以加兼容判断:

let fileInputElement = document.getElementById('bt_current_file');
try {
    // 高版本Safari/Chrome/Firefox走该逻辑
    const container = new DataTransfer();
    container.items.add(file2);
    fileInputElement.files = container.files;
} catch (err) {
    // 低版本Safari走兼容逻辑,将文件挂到input自定义属性上,提交时取该值
    fileInputElement._customFiles = [file2];
    // 提交表单时优先取_customFiles属性的值塞入FormData即可
}

三、可选优化点

现有calculateSize函数直接固定宽高会导致图片拉伸变形,建议改为等比缩放:

function calculateSize(img, maxWidth, maxHeight) {
    let width = img.width;
    let height = img.height;
    // 计算缩放比例,取最小的比例保证图片不超出最大限制
    const ratio = Math.min(maxWidth / width, maxHeight / height);
    return [width * ratio, height * ratio];
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 09:39:06