译注:原文是《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. boost.sha1

    #include <boost/uuid/sha1.hpp> #include <iostream> /* @brief SHA1摘要算法:一种很重要的密码学算法,可将任意长度 ...

  2. AndroidManifest.xml的targetSdkVersion 与 project.properties中target

    (1)minSdkVersion与maxSdkVersion :在安装程序的时候,如果目标设备的API < minSdkVersion,或者目标设备的API > maxSdkVersion ...

  3. django开发项目的部署nginx

    Django 部署(Nginx) 本文主要讲解 nginx + uwsgi socket 的方式来部署 Django,比 Apache mod_wsgi 要复杂一些,但这是目前主流的方法. 1. 运行 ...

  4. Winform 下使用WebBrowser的HTML编辑控件—WinHtmlControl 在win7 IE9下的问题

    问题是这样的,有一个需要用到富文本的地方,由于是winform的程序,而且程序是上一代老员工留下的,错误百出,现在要尽量修复,至少保证能正常使用,于是就开始一点点问题修复. 在win7 64位系统下出 ...

  5. (转) bicabo Visual Studio 2012自动添加注释(如版权信息等)

    如何使用Visual Studio 2012给程序文件的头部自动添加如下的注释? /********************************************************** ...

  6. 文件上传—SSH框架文件上传

    1.准备上传的api组件 <dependency> <groupId>commons-io</groupId> <artifactId>commons- ...

  7. mongo数据库连接工具类(C#)

    Framework版本:.Net Framework 4 using System; using System.Collections.Generic; using System.Linq; usin ...

  8. Python3.x:requests的用法

    Python3.x:requests的用法 1,requests 比 urllib.request 容错能力更强: 2,通常用法: (1).认证.状态码.header.编码.json r = requ ...

  9. GreenOpenPaint的实现(三)添加标尺

    标尺对于图像处理程序,特别是需要精确测量的程序来说意义很大.这里进行了专门的研究. 基于现在已经引入的类和定义的变量,主要讲一讲如何调用. 1.添加放大缩小 void CGreenOpenPaintD ...

  10. linux及安全第七周总结——20135227黄晓妍

    实验部分 首先clone最新的menu 我们可以看到,test.c里多了一个exec的功能,它的代码和fork基本一致,多了一项加载hello rootfs也有一些变化 执行一下exec 让我们启动一 ...