会使用传统的方式上传图片,也能够用 js 从本地读取图片,现在讨论一下一种更简单的方法来上传文件。那就是 URL 对象 。

什么是 URL 对象(object url)

URL 对象就是一个指向磁盘上文件的 url,例如,想要在浏览器中显示一个文件,而这个文件存在与用户的电脑上,通常的办法是先上传到服务器,然后在现实,但这里却不需要服务器的干预,只需要加载图片即可。上一节的讨论可以讲文件加载进一个 file 对象。将图像文件数据读取为 data URI 然后将此 data URI 加入一个 img 对象的属性中即可,但是既然图像已经存在于硬盘上,为什么还要将它读取为其他格式,然后再来使用呢?为何要多此一举呢?如果使用 URL 对象的话,那么就可以直接将硬盘里的文件付给 img 对象了。

如何工作?

File API 对全局的 URL 对象,定义了两个方法,一个是 createObjectURL() ,接受一个指向文件的参数,然后返回 URL 对象 ,这就使得浏览器能够创建和管理一个指向本地文的 URL ;另一个方法是 revokeObjectURL() ,使得浏览器可以销毁传递给它的 URL 对象,以释放内存,并且页面一旦关闭,所有的 url 对象都会被销毁。不过这样做的好处就是不需要他们的时候,浏览器可以及时释放内存。

示例:

那该怎么做呢?首先给用户一个选择文件的方式,然后将其引用到一个变量 file。然后可以使用下面的代码:

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 中,然后后创建一个 img 对象,给 img 对象一个事件,等 img 对象加载完成之后,销毁 imageUrl ,然后将此 imageUrl 付给 img 对象的 src 属性,再将其插入到页面,此时,就可以看到图像在页面上显示了。

为什么在图像加载完成之后就销毁次数据呢,因为此数据在这里只会被使用一次,所以手动的释放它以节省内存占用,但是如果还有其他用处的话,就不应该手动销毁它。

安全问题和其他注意事项

初一看,此功能有点恐怖,因为竟然可以直接加载用户的磁盘文件。当然了,这样有一些安全隐患,不过 URL 本身并没有多大的问题,因为它都是动态分配,并且在其他计算机上无法访问。

对于不同的源 File API 是不允许被使用的,当 URL 对象被创建的时候,它就被绑定到此 javascript 运行的页面,所以不可能从 www.yimity.com 访问到 post.yimity.com 页面的 URL 对象,但是两个页面都来源于 www.yimity.com ,并且一个页面是另一个页面的 iframe 的话,那就可以访问到了。

URL 对象的储存时间很短,只在文档创建他们的期间存在,一旦页面被关闭,则他们都会被销毁。所以他们不会被存储在客户端。因为页面一关闭,他们都是无用的数据了。

在 GET 请求中可以使用 URL 对象,就和正常的脚本,图像一样。但是在 post 请求中确实不可用的,例如给 form post 属性。

下一节

下一节将会有更多的关于如何处理文件数据的方式。