这是一篇来自 Jonas Sicking 的客座文章,他在 Gecko 中负责面向内容的功能开发。他介绍了我们之前讨论过的 FormData,并展示了它如何与我们在 Firefox 4 中为 File API 添加的重要部分 File.url 相连。
在 Firefox 4 中,我们继续添加对更轻松、更强大的文件处理的支持。在 Firefox 4 Beta 1 中可用的两个功能是 File.url
和 FormData
。在这篇文章中,我将简要介绍这两个功能。
从 Firefox 3.6 开始,我们支持使用 FileReader
对象来读取文件的标准化方法。这个对象允许你将文件的内容读入内存,以分析其内容或将内容显示给用户。例如,要将图像的预览显示给用户,你可以使用以下脚本
var reader = new FileReader();
reader.onload = function() {
previewImage.src = reader.result;
}
reader.readAsDataURL(myFile);
这里有两个需要注意的地方。首先,reader.result
是一个包含整个文件内容的数据 URL。也就是说,整个文件内容都保存在内存中。不仅如此,数据 URL 通常是 Base64 编码的,每个 Base64 编码的字符都存储在 JavaScript 字符中,通常使用 2 字节的内存。结果是,如果上面的代码用于读取一个 10MB 的图像文件,reader.result
将是一个 26.7MB 的字符串。
另一个不幸的是,上面的代码有点复杂,因为它需要使用异步事件从磁盘读取数据。
在 Firefox 4 Beta 1 中,你可以使用以下代码
previewImage.src = myFile.url;
这使用的是 File API 规范中定义的 File.url
属性。该属性返回一个短 URL,大约 40 个字符。你通常不需要关心这个 URL 的内容,但对于感兴趣的人来说,它包含一个由特殊方案前缀的随机生成的标识符。
这个 URL 可以用在任何使用通用 URL 的地方,从该 URL 读取直接读取文件。上面的示例使图像元素直接从文件中读取并向用户显示生成的图像。加载方式与从 HTTP URL 加载完全相同,正常的“加载”事件和“错误”事件将根据需要触发。
你也可以通过使用一个 <iframe>
并将其 src
设置为 File.url
返回的值来显示 HTML 文件。但是,你必须注意 HTML 文件中的相对 URL 不会生效,因为相对 URL 是相对于 File.url
返回的生成的 URL 解析的。这是有意为之的,因为用户可能只授予了对 HTML 文件的访问权限,而没有授予对图像文件的访问权限。
这个 URL 在其他地方也很有用,例如 CSS 背景图像,可以将元素的背景设置为使用本地文件。或者,如果你有使用 XMLHttpRequest
的现有代码,并且不想将其转换为使用 FileReader
,则可以使用 XMLHttpRequest
从该 URL 读取。
我们还在 Firefox 4 Beta 1 中支持的另一个功能是 FormData
对象。如果你有使用 multipart/form-data
编码接收文件的现有服务器基础设施,这个对象就很有用。
在 Firefox 3.6 中,使用 XMLHttpRequest
将文件发送到使用 multipart/form-data
编码的服务器需要一些手工操作。你必须使用 FileReader
将文件的内容读入内存,然后手动进行 multipart/form-data
编码,最后将其发送到服务器。这不仅需要更多代码,还需要将整个文件内容读入内存。
在 Firefox 4 中,你可以使用 XMLHttpRequest Level 2 规范中的 FormData 对象。这允许使用以下简洁的代码
var fd = new FormData();
fd.append("fileField", myFile);
var xhr = new XMLHttpRequest();
xhr.open("POST", "file_handler.php");
xhr.send(fd);
这将自动对文件进行 multipart/form-data
编码并将其发送到服务器。文件的内容将以小块的形式读取,因此不会占用大量内存。它将发送与以下标记的表单相同的内容
如果你想发送多个文件,只需对要提交的每个文件调用 fd.append
,所有文件都将通过单个请求发送。当然,你仍然可以使用 XMLHttpRequest
一直提供的正常进度事件,包括上传和下载进度事件。
但是,FormData
还有另一个不错的功能。你还可以发送正常的非文件 multipart/form-data
值。例如
var fd = new FormData();
fd.append("author", "Jonas Sicking");
fd.append("name", "New File APIs");
fd.append("attachment1", file1);
fd.append("attachment2", file2);
var xhr = new XMLHttpRequest();
xhr.open("POST", "file_handler.php");
xhr.send(fd);
你甚至可以获得一个包含 <form>
中所有信息的 FormData 对象。(但是请注意,这种语法在最终发布之前可能会发生变化)
var fd = myFormElement.getFormData();
var xhr = new XMLHttpRequest();
xhr.open("POST", "file_handler.php");
xhr.send(fd);
这里,fd
将包含表单中所有表单字段的数据,包括单选按钮和文件字段。
像往常一样,我们乐于听取你对这些功能的反馈。请告诉我们你的想法,尤其是如果你已经测试过它们,并且它们似乎没有按照你的预期工作。你可以使用 http://www.mozilla.com/en-US/firefox/beta/feedback/ 向我们提供反馈,或者使用右上角的反馈按钮(见下图)。
20 条评论