繁体   English   中英

在现代浏览器中上传文件的最佳方式是什么?

[英]What is the best way to upload files in a modern browser

我想将(单个)文件上传到服务器并显示上传的进度。

我知道我可以使用HTTP POST上传文件。 我不熟悉网络套接字,但据我所知,二进制数据也可以通过这种方式发送,因为网络套接字是双向的,我可以获得上传的进度。

我不担心旧浏览器,所以iframe和flash解决方案不是很吸引人,除非在这条路线上有明显的优势。

我也很好奇最好的服务器端技术。 使用像Django这样的WSGI服务器有什么好处? 或者像Node.js这样的非阻塞I / O技术? 我不是在问web框架x是否优于web框架y,或者服务器x是否优于服务器y。 但只是理想的技术应该具有什么才能在客户端设置上传。

更新服务器端似乎与客户端上可用的技术/ API无关,以方便上传。

编辑 (2017-10-17):截至目前,还有使用Fetch API的选项。 它提供了与基于更现代的基于承诺的API背后的XMLHttpRequest基本相同的功能。 有一种填充工具对于不支持的浏览器window.fetch()本地(主要是Internet Explorer和Safari的较旧版本的现在)。

XMLHttpRequest与Web套接字与其他东西相比

显然是XMLHttpRequest 它在现代浏览器中的功能非常庞大,几乎涵盖了所有场景。 它将产生标准的POST或PUT请求,任何Web服务器和框架组合都可以处理它。

虽然Web套接字适用于某些场景,但它是一种不同的协议,增加了许多复杂性 - 如果您需要来自服务器的实时响应,它们仅值得使用。 正如你自己所说,像Flash这样的其他方法只是丑陋的黑客攻击。

发送二进制数据

通常,您无法直接访问文件。 因此,您将在页面的某处显示<input type="file">表单字段,并等待用户选择文件。 选项是:

  • 仅发送文件内容: request.send(input.files[0]) 请求正文将是文件的内容而不是其他内容,不会执行编码,也不会传输文件名之类的元数据。 浏览器兼容性 :Chrome 7,Firefox 3.6,Opera 12,IE 10。
  • 发送整个表单的数据request.send(new FormData(input.form)) 这里表单内容将被编码为multipart/form-data ,这意味着您可以发送多个表单字段,也可以传输字段和文件名等元数据。 您也可以在发送之前修改FormData对象 根据服务器端框架,处理此请求可能比原始数据更简单,通常可以使用许多帮助程序。 浏览器兼容性 :Chrome 6,Firefox 4,Opera 12,IE 10。
  • 发送一个类型化数组 :以防万一你没有文件而只是想发送一些你动态生成的二进制数据。 这里没有执行额外的编码,因此就服务器端而言,这就像发送文件内容一样。 浏览器兼容性 :Chrome 9,Firefox 9,Opera 11.60,IE 10。

显示上传进度

您可以XMLHttpRequest.upload上侦听progress事件 loaded progress事件total属性,可以确定您的请求已达到多远。 浏览器兼容性 :Chrome 7,Firefox 3.5,Opera 11.60,IE 10。

JavaScript库

当然,现有的库包含了此处概述的功能。 这些在其他答案中提到,在网上搜索肯定会更多。 我明确地不想在这里提出任何库 - 如果你应该使用它们中的哪一个纯粹是一个偏好问题。

我的答案很晚,但在这里:


简短回答:

XMLHttpRequest是在现代浏览器中上传文件的最佳方式。



什么是XMLHttpRequest?

XMLHttpRequest是一个由Microsoft设计并由Mozilla,Apple和Google采用的JavaScript对象。 它现在正在W3C中进行标准化 它提供了一种从URL检索数据的简便方法,而无需进行整页刷新。 网页只能更新页面的一部分,而不会中断用户的操作。 XMLHttpRequest在AJAX编程中大量使用。

尽管名称如此,但XMLHttpRequest可用于检索任何类型的数据,而不仅仅是XML ,它支持HTTP以外的协议 (包括文件和ftp )。

XMLHttpRequest对象已经在Html5规范中得到了改进。 特别是XMLHttpRequest Level 2


好处:

  • 处理字节流,如FileBlobFormData对象,以便上载和下载
  • 上传和下载过程中的进度事件
  • 跨域请求
  • 允许发出匿名请求 - 即不发送HTTP Referer
  • 为请求设置超时的功能
  • 上传正在后台进行
  • 用户所在页面保持不变
  • 不需要对服务器端进行任何更改 ,因此现有的服务器端逻辑应保持不变,这使得更容易调整此技术。

Html5进展事件:

根据Html5 Progress Events规范 ,Html5进度事件提供了以下信息:

total - Total bytes being transferred
loaded - Bytes uploaded thus far
lengthComputable - Specifies if the total size of the data/file being uploaded is known 

使用上述信息,向用户提供“剩余时间”信息相当容易。


让用户知情:

有关可供用户使用的文件的信息:

  1. 文件名
  2. 文件大小
  3. 哑剧类型
  4. 完成百分比的进度条
  5. 上传速度或上传带宽
  6. 剩余的大致时间
  7. 到目前为止上传的字节数
  8. 来自服务器端的响应

使用XMLHttpRequest演示文件上传

请查看“ 使用带有进度指示演示的Html5上载文件 ”作为示例。 所需的所有JavaScript代码都在页面中,但不包含CSS。 出于安全原因,文件类型仅限于jpg,png,gif和txt。 最大文件大小为2MB。


XMLHttpRequest浏览器兼容性:

XMLHttpRequest浏览器兼容性


可能Javascript的文件API是现代浏览器中的最佳方式:

http://robertnyman.com/2010/12/16/utilizing-the-html5-file-api-to-choose-upload-preview-and-see-progress-for-multiple-files/

http://www.sitepoint.com/html5-javascript-file-upload-progress-bar/

服务器方面...我认为任何主要框架都有很好的覆盖HTTP文件POST功能。

文件可以通过AJAX上传。

使用jQuery表单插件 它完成了将文件绑定到表单并将其序列化的所有脏工作。 它还能够显示上传进度。

服务器堆栈与它没有多大关系。

演示

我个人喜欢blueimp jQuery文件上传插件( https://blueimp.github.io/jQuery-File-Upload/

文件上传小工具,包含多个文件选择,拖放支持,进度条,验证和预览图像,jQuery的音频和视频。 支持跨域,分块和可恢复文件上传以及客户端图像大小调整。 适用于支持标准HTML表单文件上载的任何服务器端平台(PHP,Python,Ruby on Rails,Java,Node.js,Go等)。

演示:

下载(GitHub): https //github.com/blueimp/jQuery-File-Upload

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM