Blob createObjectURL download 在 Firefox 中无法正常工作的解决方法

问题描述

在前端开发中,我们经常需要通过 Blob 对象来生成文件并提供下载。其中一种常用的方式是使用 createObjectURL() 方法来创建一个 URL,并将其赋值给一个链接标签的 href 属性上,让浏览器自动下载该文件。例如:

----- ---- - --- ------------ -------- - ----- ------------ ---
----- --- - --------------------------
----- ---- - ----------------------------
--------- - ----
------------- - ------------
--------------------------------
-------------

但是,有些用户反馈说这种方式在 Firefox 浏览器中无法正常工作,点击链接后无法下载文件。

分析原因

经过排查,我们发现这个问题与 Firefox 的安全策略有关。Firefox 限制了对于跨站点(Cross-Origin)资源的 download 属性的使用,只有在以下情况下才允许使用:

  1. 资源与当前页面在同一个域名下或是子域名下。
  2. 资源的服务器返回 Access-Control-Allow-Origin 头信息,并且允许当前页面所在的域名访问。

在使用 createObjectURL() 方法生成的 URL 中,协议和域名都是 blob:,不符合上述要求。因此,在 Firefox 中,当我们点击链接时,浏览器会根据安全策略进行阻止,导致无法下载文件。

解决方法

解决这个问题的方法比较简单,只需要使用另一种方式来生成能够满足 Firefox 安全策略的 URL 就可以了。这里我们可以使用 Blob 对象的 text() 方法或者 FileReader 对象的 readAsDataURL() 方法来生成一个 Base64 编码的字符串,并将其作为链接地址即可:

----- ---- - --- ------------ -------- - ----- ------------ ---
----- ------ - --- -------------
---------------------------
------------- - ---------- -
  ----- ---- - ----------------------------
  --------- - --------------
  ------------- - ------------
  --------------------------------
  -------------
--

上面的代码中,我们使用 FileReader 对象读取 Blob 对象中的内容,并通过 onload 事件获取到 Base64 编码的字符串,然后将其作为链接地址。这种方式在 Firefox 中也可以正常工作。

指导意义

在开发前端应用程序时,我们要时刻考虑到浏览器的安全策略,尤其是跨域资源访问的问题。为了避免出现类似上述问题,我们应该使用符合安全策略的方式来访问跨域资源,例如使用 CORS 或 JSONP 等技术,以及合适的认证和授权机制。

同时,在遇到类似问题时,我们要深入分析问题的原因,并寻找合适的解决方法。在上述问题中,我们通过学习 Firefox 的安全策略,以及使用 FileReader 对象来生成 Base64 编码的链接地址,解决了这个问题。

参考资料

来源:JavaScript中文网 ,转载请联系管理员! 本文地址:https://www.javascriptcn.com/post/28163


猜你喜欢

  • 如何获取以某个字符串开头的所有元素?

    在前端开发中,我们经常需要根据一些特殊的需求来选择特定的元素进行处理。其中,一个常见的需求是获取所有元素名以某个特定字符串开头的元素。 方法一: 使用 querySelectorAll() 方法 可以...

    7 年前
  • 如何在 Backbone.js 视图中触发 / 绑定自定义事件?

    在 Backbone.js 中,除了内置的事件(如 change 和 click),我们还可以定义和使用自定义事件。这些自定义事件可以让我们更好地组织代码,提高代码的可读性和可维护性。

    7 年前
  • jQuery + Moment.js:从日期获取星期几名称

    在开发 Web 应用程序时,我们经常需要处理日期和时间。Moment.js 是一个流行的 JavaScript 库,它使得处理日期和时间变得更加容易和方便。而结合 jQuery,我们可以更快速地操控D...

    7 年前
  • Bootstrap 4: Uncaught ReferenceError: Popper is not defined

    在使用 Bootstrap 4 进行开发时,你可能会遇到这个错误:Uncaught ReferenceError: Popper is not defined。这个错误通常出现在使用 Bootstra...

    7 年前
  • Protractor 测试:如何在登录表单中设置文本元素的值?

    Protractor 是一个流行的端到端测试框架,它可以帮助前端开发人员和测试工程师自动化测试 AngularJS 应用程序。在使用 Protractor 进行测试时,我们经常需要设置表单元素的值。

    7 年前
  • Binding value to input in Angular JS

    在Angular JS中,绑定(Binding)是实现双向数据绑定的关键。它可以将模型(Model)和视图(View)连接起来。在本文中,我们将深入探讨如何在Angular JS中将值绑定到输入框。

    7 年前
  • Knockout JS 2.0 在 IE 中的绑定解析错误

    Knockout JS 是一款流行的 JavaScript 库,通过实现 MVVM(Model-View-ViewModel)模式,使开发人员可以轻松地创建动态的前端界面。

    7 年前
  • 使用 jQuery 解析 XML 的方法

    XML 是一种常用的数据格式,前端开发中也经常需要使用到 XML 数据。本文介绍如何使用 jQuery 解析 XML 数据,并附有示例代码。 什么是 XML? XML(可扩展标记语言,Extensib...

    7 年前
  • 如何测试函数是否提供了参数?

    在编写 JavaScript 函数时,常常需要测试函数是否正确地接收和处理参数。在本文中,我们将介绍几种测试函数是否提供参数的方法。 方法一:使用 arguments 对象 JavaScript 中的...

    7 年前
  • JavaScript 中使用 $ 符号声明匿名函数的含义及用法

    在 JavaScript 中,我们经常会看到一些以 $ 符号开头的匿名函数,例如: ------------ - -- -- --------- ---- ---这种写法是什么意思呢?为什么要使用...

    7 年前
  • jQuery Selector + SVG 不兼容?

    在前端开发中,jQuery 是一个广泛使用的 JavaScript 库。然而,有时候会遇到 jQuery 选择器与 SVG 图形不兼容的问题。本文将深入探讨这个问题,并提供解决方案。

    7 年前
  • JavaScript YAML Parser

    YAML 是一种人类可读性高、数据结构清晰的语言,常用于配置文件和数据序列化。JavaScript YAML Parser 是一个解析器,可以将 YAML 格式的文本转换为 JavaScript 对象...

    7 年前
  • 如何测试元素是否已经使用了 jQuery Datepicker

    jQuery Datepicker 是一个常用的前端日期选择器插件,它提供了丰富的选项和样式,并且可以轻松地集成到网站中。但有时候我们需要在代码中判断某个元素是否已经使用了 Datepicker 插件...

    7 年前
  • 使用Javascript生成CSS中更轻/更暗的颜色

    在Web开发中,我们经常需要根据设计要求调整网页的颜色。有时候我们需要比原始颜色更明亮或更暗的变体。本文将介绍如何使用JavaScript生成CSS中更轻或更暗的颜色变体。

    7 年前
  • 阻止点击 div 时触发 focus 事件

    在前端开发中,我们通常需要在页面上给某些元素绑定事件。其中,focus 事件是一个很常见的事件,它会在用户聚焦到某个元素(如 input、textarea 等)时触发。

    7 年前
  • Underscore contains (_.contains) 在对象类型上的应用

    Underscore.js 是一个流行的 JavaScript 库,提供了许多实用的函数来操作数组、集合、对象等数据类型。其中,contains 函数可以用于判断一个值是否存在于一个数组或字符串中。

    7 年前
  • 在Angular.js中如何从一个过滤器调用另一个过滤器

    在Angular.js开发中,过滤器是一种非常有用的工具,它可以帮助我们处理和转换数据。在某些情况下,我们可能需要从一个过滤器中访问另一个过滤器,以便更好地处理数据。

    7 年前
  • Javascript 中的 "options = options || {}" 是什么意思?

    在很多 JavaScript 库和框架中,我们会经常看到类似 options = options || {} 的代码。那么这行代码到底是做什么的呢? 什么是 options? 在JavaScript...

    7 年前
  • 使用表单验证:为什么要使用 onsubmit="return functionname()" 而不是 onsubmit="functionname()"?

    在编写前端代码时,表单验证是一个必不可少的任务。表单验证可以确保用户提交的数据符合预期,并且可以防止非法输入和攻击。但是,在处理表单验证时,我们经常会遇到一个问题:应该使用 onsubmit="ret...

    7 年前
  • event.wheelDelta 返回 undefined

    在前端开发中,我们经常需要通过事件监听来处理用户输入。其中,鼠标滚轮事件是一个常见的交互操作,但在处理该事件时,您可能会遇到 event.wheelDelta 属性返回 undefined 的情况。

    7 年前

相关推荐

    暂无文章