译注:原文是《JavaScript高级程序设计》的作者Nicholas Zakas写的,本翻译纯属为自己学习而做,仅供参考。原文链接:这里


学习到这里,你已经了解在传统方式中如何使用文件,你可以上传文件到服务端,可以从磁盘上读取文件,这些都是最常见的文件处理方式。但是,有一种全新的文件处理方式可以简化这些常见的任务,这就是使用对象URLs。

什么是对象URL?

对象URLs是磁盘上的文件地址。比如说,你想要将用户系统的一个图像文件显示到web页面,服务端无需要知道这个文件,所以也不需要上传它。如果你只是想要加载文件到页面,你可以像之前的帖子说的一样,获取一个File对象引用,将数据读取为一个数据URI,然后将数据URI分配到一个<img>元素。但想一想这里面的浪费,图像已经在磁盘上存在,为什么还要将图像读取为另外一种形式呢?如果你创建一个对象URL,你可以将其分配给<img>,这样就可以直接访问本地文件。

它如何工作?

File API[1]定义了一个全局对象叫URL,它有2个方法。第一个是createObjectURL(),接受一个File对象作为参数,返回一个对象URL,作用是告诉浏览器创建并且管理一个本地文件的URL。第二个方法是revokeObjectURL(),作用是告诉浏览器去销毁作为参数传入的URL,有效的释放内存。当然,一旦web页面被卸载了,则所有对象URLs都会被注销,当不再需要它们的时候,这是释放它们内存的一个好机会。

File API对URL对象的支持不像其他部分那么好,在我写这篇文章的时候,IE10和Firefox9+支持一个全局URL对象。Chrome支持它的webkitURL形式,Safari和Opera不支持。

例子

如果你没有读取图片文件的数据,你怎么显示这个图片呢?假设你已经提供给用户文件选择的方式,并且现在有这个文件对象的引用并赋给了一个变量file。你可以如下使用:

1
2
3
4
5
6
7
8
9
10
var URL = window.URL || window.webkitURL, imageUrl, image;
if (URL) {
  imageUrl = URL.createObjectURL(file);
  image = document.createElement("img");
  image.onload = function() {
    URL.revokeObjectURL(imageUrl);
  };
  image.src = imageUrl;
  document.body.appendChild(image);
}

这个例子创建了一个本地URL变量,标准化浏览器的实现(即无论是何种浏览器都可以得到)。如果URL存在,程序将创建一个文件对象URL并将其存储在变量imageUrl,然后创建一个新的元素,将imageUrl传入该元素的onloade事件处理方法,该方法将注销对象URL(一分钟内)。然后,src属性被分配了一个对象URL并将元素添加到页面。

当图片加载的时候为什么要注销对象URL呢?在图片加载完之后,该URL就不再需要了,除非你想要在另外一个元素里面复用它。在这个例子中,图片被加载到一个单独的元素中,并且一旦图片完成加载,该URL就不再起任何作用,这是释放任何与其关联的内存的绝佳时刻。

安全和注意事项

乍一看,这种能力有点恐怖。实际上你是通过一个URL直接从用户机器上加载一个文件,这种方式当然存在安全隐患。URL本身其实不是一个大的安全问题,因为URL是通过浏览器动态分配的,在其他电脑上不会起作用。那跨网点会怎么样呢?

File API 不允许在不同网点使用对象URLs。当一个对象URL被创建,它就紧跟着执行JavaScript脚本的页面网点,所以你不能跨www.wrox.com和p2p.wrox.com两个不同网点使用同一个对象URL(会发生错误)。但是,如果两个页面都是来自www.wrox.com,比如其中一个页面嵌套在另外一个页面的iframe里,这样就可以共享对象URLs。

对象URLs只存在于文档创建它们的时候。当文档被卸载,所有对象URLs都会被注销。所以,在客户端存储对象URLs以便以后使用是没有意义的,它们在页面卸载之后就没有用了。

你可以在浏览器中任何一个发起get请求的地方使用对象URLs,其中包括图片,脚本,web worker,样式表,音频,视频。浏览器执行post请求时使用不了对象URL。


下集预告

创建直接链接到本地文件的URL是一种很强的能力。对比读取一个本地文件到JavaScript然后在页面上显示,你可以简单地创建一个URL并在页面指定它,后者大大简化了本地文件在页面中的使用情况。尽管如此,JavaScript处理文件有趣的地方才刚刚开始。在下一篇blog,你将学习到一些有趣的方式来处理文件数据。

相关链接

  1. File API

在JavaScript中进行文件处理,第四部分:对象URLs的更多相关文章

  1. 在JavaScript中进行文件处理,第五部分:Blobs

    译注:原文是<JavaScript高级程序设计>的作者Nicholas Zakas写的,本翻译纯属为自己学习而做,仅供参考.原文链接:这里 到目前为止,这个系列的帖子集中在和这些文件交互- ...

  2. 在JavaScript中进行文件处理,第一部分:基础

    译注:原文是<JavaScript高级程序设计>的作者Nicholas Zakas写的,本翻译纯属为自己学习而做,仅供参考.原文链接:这里 很多年前,我在一次Goole面试被问到,如何在w ...

  3. 在JavaScript中进行文件处理,第二部分:文件读取

    译注:原文是<JavaScript高级程序设计>的作者Nicholas Zakas写的,本翻译纯属为自己学习而做,仅供参考.原文链接:这里 在我的前一篇blog中,我介绍了在JavaScr ...

  4. 在JavaScript中进行文件处理,第三部分:处理事件和错误

    译注:原文是<JavaScript高级程序设计>的作者Nicholas Zakas写的,本翻译纯属为自己学习而做,仅供参考.原文链接:这里 FileReader对象用来读取浏览器可以访问的 ...

  5. JavaScript中的 原型 property 构造函数 和实例对象之间的关系

    1 为什么要使用原型? /* * javascript当中 原型 prototype 对象 * * */ //首先引入 prototype的意义,为什么要使用这个对象 //先来写一个构造函数的面向对象 ...

  6. javascript中使用new与不使用实例化对象的区别

    我们先来看个实例 function Me(name,age,job){ this.name = name; this.age = age; this.job = job; } 请问这以下两种实例化对象 ...

  7. JavaScript中推断一个对象是否为&quot;空对象”

    JavaScript中推断一个对象是否为"空对象" 这里指的"空对象"是类似于:{ } 和 new Object() 这种. 详细的代码实现和原理例如以下: / ...

  8. javaScript中小数取整,四种方法的比较

    1.parseInt:只取整数位例如:parseInt(3.7) 取整结果为:3parseInt(-1.1) 取整结果为:-1 2.Math.floor :向下去整,取大的整数例如:Math.floo ...

  9. javascript中无法将string转化为json对象

    在一次项目之中,我要对请求的相应做一些处理,得到的响应差不多是这中格式'{total:1,result:[{"age":1}]}'.可以看到我拿到的这个相应和JSON的格式是非常相 ...

随机推荐

  1. Ubuntu操作异常汇总

    1.使用Ubuntu的apt-get安装软件时出现以下错误: Reading package lists... Done Building dependency tree... Done Packag ...

  2. 当IDENTITY_INSERT设置为OFF时不能向表插入显示值。(源:MSSQLServer,错误码:544)

    错误提示"事务和快照同步时提示:当IDENTITY_INSERT设置为OFF时不能向表插入显示值.(源:MSSQLServer,错误码:544)" 原因:在SQL2008同步时到S ...

  3. django高级之点赞、文章评论及上传文件

    目录: 点赞 文章评论 上传文件 保留页面条件 一.点赞 1.所用技术: django model F查询 js应用:$(function () {}); 为文件加载完成执行ready() 方法.等同 ...

  4. 《TP5.0学习笔记---模型篇》

    https://blog.csdn.net/self_realian/article/details/78596261 一.什么是模型 为什么我们要在项目中使用模型,其实我们知道,我们可以直接在控制器 ...

  5. 命令行下开启与关闭windows防火墙关端口(转)

    sc config sharedaccess start= auto //设置防火墙服务为自动 net start sharedaccess //开启防火墙服务 关闭端口 netsh firewall ...

  6. ACM-ICPC 2018 沈阳赛区网络预赛 Solution

    A. Gudako and Ritsuka 留坑. B. Call of Accepted 题意:定义了一种新的运算符$x d y$ 然后给出中缀表达式,求值 思路:先中缀转后缀,然后考虑如何最大如何 ...

  7. Python面试题之Python中的类和实例

    0x00 前言 类,在学习面向对象我们可以把类当成一种规范,这个思想就我个人的体会,感觉很重要,除了封装的功能外,类作为一种规范,我们自己可以定制的规范,从这个角度来看,在以后我们学习设计模式的时候, ...

  8. 前端学习笔记之CSS网页布局

    CSS网页布局   阅读目录 一 网页布局方式 二 标准流 三 浮动流 四 定位流 一 网页布局方式 #1.什么是网页布局方式 布局可以理解为排版,我们所熟知的文本编辑类工具都有自己的排版方式,比如w ...

  9. Python3:sqlalchemy对mysql数据库操作,非sql语句

    Python3:sqlalchemy对mysql数据库操作,非sql语句 # python3 # author lizm # datetime 2018-02-01 10:00:00 # -*- co ...

  10. 怎样快速掌握一个用你没学过的框架写的PHP项目?

    我的思路一般是先搞定框架的route.也就是说,明白一个请求的url地址是对应的哪个controller处理的,找到controller后,再理解一下它的类库加载方案,也就是说一些辅助类以及自己逻辑类 ...