译注:原文是《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. How Instagram Feeds Work: Celery and RabbitMQ(转)

    原文:http://blogs.vmware.com/vfabric/2013/04/how-instagram-feeds-work-celery-and-rabbitmq.html Instagr ...

  2. Linux学习 -->解决Ubuntu系统上 No command 'crond' found

    前两天,准备在Ubuntu服务器上,定时执行Gitlab备份的命令,如下所示 编辑 vi /etc/crontab 文件,添加如下定时脚本 # edited by ouyang 2017-8-11 添 ...

  3. MongoDB: 原子性和事务

    在MongoDB中, 文档级别的的写操作是原子性的, 甚至是在对某个文档的操作中修改其多个内嵌的子文档, 也是原子性的. 在一个写操作同时修改多个文档的情况, 对其中单独的某个文档而言是原子的, 但是 ...

  4. appfog 使用

    1.需要安装ruby 和 devkit The RubyInstaller Development Kit (DevKit) is a MSYS/MinGW based toolkit than en ...

  5. android qq开合表

    qq悬浮列表功能暂未实现 main.xml <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/andr ...

  6. orcle中如何使用动态游标来对变量进行赋值

    在oracle中动态游标的概念一般不常用,但有时根据客户的特殊业务,需要使用到动态游标来解决问题!在对于一条动态SQL语句而产生多条记录时,动态游标的使用将是一个很好的选择,具体参见如下在工作流项目中 ...

  7. 9.python的列表

    list2 = [1, 2, 3, 4, 5, 6, 7 ]; print ("list2[1:5]: ", list2[1:5]) 得到 list2[1:5]:  [2, 3, ...

  8. Django之logging日志使用

    Logger模块 是python中用于便捷记录日志且线程安全的模块 使用logging模块记录日志涉及四个主要类: logger提供了应用程序可以直接使用的接口: handler将(logger创建的 ...

  9. Jmeter之Constant Timer与constant throughput timer的区别

    当放置Constant Timer于两个http请求之间,那么它代表的含义是:在上一个请求发出至完成后, 开始Contant Timer指定的时间,最后再发出第二个请求.它并不是代表两个请求之间的发送 ...

  10. 3.1 Templates -- Handlerbars Basics(Handlerbars基础知识)

    一.简介 Ember.js使用Handlerbars模板库来强化应用程序的用户界面.它就像普通的HTML,但也给你嵌入表达式去改变现实的内容. Ember使用Handlerbars并且用许多新特性去扩 ...