根据您评论中的要求,这里是对我的评论的更完整解释。
至于跟踪上传进度,这是可能的,无需编写特定的服务器端代码来支持跟踪上传进度。正如您所提到的,我说的onprogress
是 XMLHttpRequest level 2 提供的事件。它很容易使用。看看我刚才提到的链接的一小部分:
var oReq = new XMLHttpRequest();
oReq.addEventListener("progress", updateProgress, false);
oReq.open();
oReq.send(something);
// progress on transfers from the server to the client (downloads)
function updateProgress (oEvent) {
if (oEvent.lengthComputable) {
var percentComplete = oEvent.loaded / oEvent.total;
// ...
} else {
// Unable to compute progress information since the total size is unknown
}
}
至于您问题中提到的其他项目:
我想区分“上传文件”和“等待响应”,以便向用户显示相应的消息/指示图标等。
这在理论上当然是可能的。我在我维护的跨浏览器上传库Fine Uploader中所做的是等到最后一个字节已发送(根据我的进度处理程序),然后在 UI 中的文件旁边添加一条消息,例如“处理。 ……”。我假设,随着最后一个字节的发送,服务器正在对文件执行一些任务,我现在只是在等待响应。
我说这在理论上是可以检测到的,但实际上不能跨浏览器检测。为什么?我在Fine Uploader Github 存储库中的一个案例中对此发表了评论。我将在此处包含我的全部评论:
我注意到 Firefox 在收到服务器的响应之前不会触发它的最后一个进度事件,这有点令人沮丧。提交了一个Firefox 问题来跟踪此“问题”。
听起来 Firefox 可能实际上是在遵循 XHR V2 规范的字母,而 Chrome 则在坚持规范的“精神”。Chrome 的实现会导致在“发送”最后一个字节后触发最后一个进度事件,这是大多数人所期望的,但这可能只是违反规范。不确定 IE10 做了什么,因为我还没有研究过。一位 FF 开发人员在 w3.org 上打开了一个帖子,要求澄清一下。
Chromium 开发人员认为“预期”行为实际上是 webkit 细节,而不是特定于 Chrome。这表明 Safari 和 Chrome 表现出相同的行为,我已经验证了这一点。听起来好像有必要调整规范以允许 webkit 的行为成为预期的行为(根据规范的字母)。
请注意,我没有使用“loadend”事件来确定浏览器何时完成发送最后一个字节。在处理“进度”事件通知时,我只是将“加载”值与“总”值进行比较。如果这两个值相等,我声明文件“完全发送”。根据规范,我应该能够做到这一点(我认为),因为“loadend”事件只是在最后一个“progress”事件之后触发。有关更多详细信息,请参阅有关ProgressEvent的规范。
总而言之,这在 Chrome 和 Safari 中运行良好,但在 FireFox 中运行良好。我不记得这是否适用于 IE10。我不记得了,因为我很少使用 IE。在 Firefox 中,进度指示器会在接近 99% 左右时卡住,直到收到响应。
请注意,所有这些进度跟踪只有在用户代理支持文件 API 的情况下才能实现。这忽略了 IE9 和更早版本。对于非文件 API 浏览器,有几个选项:
- 建立某种约定,涉及客户端和服务器可以理解的 GET 请求。客户端会定期向服务器发送 GET 请求,服务器必须响应文件进度。FYI Fine Uploader 有一个预定的功能请求来进一步研究这个问题,尽管我对这种方法并不是很着迷。
- 另一种选择,看起来更好一点,但可能有更多限制(因为它取决于应用程序服务器)是使用 nginx 中的 UploadProgress 模块(如果您不熟悉,则发音为 Engine-X)。有人告诉我 Apache 有一个类似的模块,但我无法找到任何文档(尽管我根本没有研究这么多)。Fine Uploader 也有 [对此的功能请求 ( https://github.com/Widen/fine-uploader/issues/506 ),我也将在不久的将来进行调查。
希望这能回答你的问题。