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

JS实现vcf文件下载时Safari保存为example.com问题

问题原因

Safari 对 <a> 标签直接关联的 data URI 资源有特殊实现逻辑:当 href 属性值为 data URI 时,Safari 会直接忽略 download 属性指定的文件名,默认取当前页面域名作为下载文件名,这就是下载文件被命名为 example.com 的核心原因,和download属性的语法书写无关。

修复方案
  • 放弃直接拼接 data URI 赋值给href的写法,改用 Blob 配合 URL.createObjectURL() 生成临时资源地址,这套实现在全版本主流浏览器(包括Safari)下都能正确读取download属性配置的文件名。
  • 对齐vCard格式标准:vCard 3.0规范要求行尾必须使用CRLF换行符(即\r\n),不要单独使用\n,避免部分Safari版本因解析vCard格式失败连带触发文件名识别异常。
  • 调整DOM移除时机:触发a标签点击事件后不要立刻移除元素,添加短延时等待Safari完成下载事件响应,同时记得释放生成的临时Blob URL避免内存泄漏。
核心修正代码

替换原有download函数为以下实现:

function download(filename, text) {
  // 生成vCard格式的Blob对象,指定正确MIME类型
  const vcardBlob = new Blob([text], { type: 'text/vcard;charset=utf-8' });
  const downloadLink = document.createElement('a');
  // 生成临时Blob访问地址
  const blobUrl = URL.createObjectURL(vcardBlob);
  downloadLink.href = blobUrl;
  downloadLink.setAttribute('download', filename);

  downloadLink.style.display = 'none';
  document.body.appendChild(downloadLink);
  downloadLink.click();

  // 延迟清理临时地址和DOM元素,兼容Safari事件响应逻辑
  setTimeout(() => {
    URL.revokeObjectURL(blobUrl);
    document.body.removeChild(downloadLink);
  }, 100);
}

同时修改vCard内容拼接的换行符,所有行尾的\n替换为\r\n,例如初始vCard头修改为:

let vcard_start ="BEGIN:VCARD\r\nVERSION:3.0\r\n"

后续拼接FN、N、EMAIL等每一行字段时,行尾统一使用\r\n即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 09:54:28