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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29659154/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 03:44:52  来源:igfitidea点击:

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

javascriptdjangohttpfile-uploadwebsocket

提问by Tom

I want to upload a (single) file to a server and show the progress of the upload.

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

I know I can upload a file using HTTP POST. I'm not familiar with web-sockets, but as I understand, binary data can also be sent that way and because web sockets are bi-directional I could get the progress of the upload.

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

I'm not worried about older browsers so iframe's and flash solutions aren't very appealing unless there is a significant advantage in going that route.

我不担心旧浏览器,因此 iframe 和 Flash 解决方案不是很吸引人,除非在这条路线上有显着优势。

I'm also curious as to the best server-side technology. Are their advantages to using a WSGI server like Django? Or maybe non-blocking I/O technology like Node.js? I'm not asking if web framework x is better than web framework y, or server x is better than server y. But simply what the ideal technology should have in order to facility uploads in the client.

我也很好奇最好的服务器端技术。他们使用像 Django 这样的 WSGI 服务器的优势是什么?或者像 Node.js 这样的非阻塞 I/O 技术?我不是在问 web 框架 x 是否比 web 框架 y 更好,或者服务器 x 是否比服务器 y 更好。但只是为了方便在客户端上传,理想的技术应该具备什么。

Update: It seems like the server side does not have bearing on the technologies/API's available on the client to facilitate uploads.

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

采纳答案by Wladimir Palant

Edit(2017-10-17): As of now, there is also the option to use Fetch API. It offers essentially the same capabilities as XMLHttpRequest behind a more modern promise-based API. There is a polyfillfor browsers that don't support window.fetch()natively (which is mainly Internet Explorer and older Safari versions right now).

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

XMLHttpRequest vs. Web sockets vs. Something else

XMLHttpRequest 与 Web 套接字与其他东西

Clearly XMLHttpRequest. Its capabilities in modern browsers are enormous and cover almost all scenarios. It will produce a standard POST or PUT request, any web server and framework combination can deal with that.

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

While web sockets are nice for some scenarios, it's a different protocol that adds lots of complexity - they are only worth using if you need real-time responses from the server. And as you noted yourself, other approaches like Flash are merely ugly hacks.

虽然网络套接字在某些情况下很好,但它是一种不同的协议,会增加很多复杂性 - 只有在您需要来自服务器的实时响应时才值得使用。正如您自己指出的那样,其他方法如 Flash 只是丑陋的黑客。

Sending binary data

发送二进制数据

Normally, you won't have direct access to files. So you will have an <input type="file">form field somewhere on your page and wait for the user to choose a file. The options then are:

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

  • Sending only the file contents: request.send(input.files[0]). The request body will be the file's contents and nothing else, no encoding will be performed and no metadata like file name will be transmitted. Browser compatibility: Chrome 7, Firefox 3.6, Opera 12, IE 10.
  • Sending the data of the entire form: request.send(new FormData(input.form)). Here the form contents will be encoded as multipart/form-data, meaning that you can send multiple form fields and metadata like field and file names will be transmitted as well. You can also modify the FormDataobjectbefore sending it. Depending on the server-side framework, handling this request might be simpler than raw data, there are typically many helpers you can use. Browser compatibility: Chrome 6, Firefox 4, Opera 12, IE 10.
  • Sending a typed array: just in case you don't have a file but merely want to send some binary data you generate on the fly. No extra encoding is being performed here, so as far as the server side is concerned this works like sending file contents. Browser compatibility: Chrome 9, Firefox 9, Opera 11.60, IE 10.
  • 仅发送文件内容: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。

Displaying upload progress

显示上传进度

You can listen to progressevents on XMLHttpRequest.upload. The progresseventshave loadedand totalproperties that allow determining how far you've got with your request. Browser compatibility: Chrome 7, Firefox 3.5, Opera 11.60, IE 10.

您可以在 上收听progress事件XMLHttpRequest.upload。该progress事件loadedtotal,使确定你在多大程度上符合你的要求得到了性能。浏览器兼容性:Chrome 7、Firefox 3.5、Opera 11.60、IE 10。

JavaScript libraries

JavaScript 库

There are of course existing libraries wrapping the functionality outlined here. These are mentioned in other answers, searching on the web will certainly turn up even more. I explicitly don't want to propose any libraries here - which of them if any you should use is purely a matter of preference.

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

回答by CONvid19

My answer is quite late but here it goes:

我的回答已经很晚了,但它是这样的:



Short answer:

简短的回答:

XMLHttpRequestis the best way to upload files in a modern browser.

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





What is XMLHttpRequest?

什么是 XMLHttpRequest?

XMLHttpRequest is a JavaScriptobject that was designed by Microsoft and adopted by Mozilla, Apple, and Google. It's now being standardized in the W3C. It provides an easy way to retrieve data from a URL without having to do a full page refresh. A Web page can update just a part of the page without disrupting what the user is doing. XMLHttpRequest is used heavily in AJAXprogramming.

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

Despite its name, XMLHttpRequest can be used to retrieve any type of data, not just XML, and it supports protocols other than HTTP(including file and ftp).

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

The XMLHttpRequestobject has gotten a facelift in the Html5specifications. Specifically the XMLHttpRequest Level 2.

XMLHttpRequest对象已在Html5规范中进行了翻新。特别是XMLHttpRequest Level 2



Advantages:

好处:

  • Handling of byte streams such as File, Bloband FormDataobjects for uploading and downloading
  • Progress eventsduring uploading and downloading
  • Cross-originrequests
  • Allow making anonymous request- that is not send HTTP Referer
  • The ability to set a Timeoutfor the Request
  • Uploading is happening in the background
  • The page the user is on remains intact
  • Does not require any change to the server side, so existing server side logic should remain unchanged, which makes adapting this technology that much easier.
  • 处理字节流,如FileBlobFormData对象以供上传和下载
  • 上传和下载期间的进度事件
  • 跨域请求
  • 允许进行匿名请求- 即不发送 HTTP Referer
  • 为请求设置超时的能力
  • 上传正在后台进行
  • 用户所在页面保持不变
  • 不需要对服务器端进行任何更改,因此现有的服务器端逻辑应该保持不变,这使得适应这项技术变得更加容易。


The Html5 Progress Event:

Html5 进度事件:

As per the Html5 Progress Events spec, the Html5 progress event provides, among others, the following information :

根据Html5 进度事件规范,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 

Using the information above, it is fairly easy to provide the "Time remaining" information to the user.

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



Keep the user informed:

通知用户:

Information about the file that can be made available to the user:

有关可以提供给用户的文件的信息:

  1. File Name
  2. File Size
  3. Mime Type
  4. A Progress bar with percent complete
  5. The upload speed or upload bandwidth
  6. The approximate time remaining
  7. The bytes uploaded thus far
  8. A response from the server side
  1. 文档名称
  2. 文件大小
  3. 哑剧类型
  4. 带有完成百分比的进度条
  5. 上传速度或上传带宽
  6. 大约剩余时间
  7. 到目前为止上传的字节数
  8. 来自服务器端的响应


File Upload using XMLHttpRequest Demo

使用 XMLHttpRequest Demo 上传文件

Please check "Uploading files using Html5 with Progress indication demo" for an example. All of the JavaScript code required is in the page but no CSS is included. For security reasons, the file types are limited to jpg, png, gif and txt. Max file size is 2MB.

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



XMLHttpRequest Browser Compatibility:

XMLHttpRequest 浏览器兼容性:

XMLHttpRequest Browser compatibility

XMLHttpRequest 浏览器兼容性



回答by vtortola

Probably the Javascript's file API is the best way in modern browsers:

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

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

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://www.sitepoint.com/html5-javascript-file-upload-progress-bar/

Server side wise... I think any of the main frameworks has the HTTP file POST feature well covered.

服务器端明智...我认为任何主要框架都很好地涵盖了 HTTP 文件 POST 功能。

回答by xyres

Files can be uploaded via AJAX.

文件可以通过 AJAX 上传。

Use the jQuery form plugin. It does all the dirty work of binding the files to the form and serializing it. It is also capable of showing upload progress.

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

Server stack hasn't got much to do with it.

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

Demo

演示

回答by ptCoder

I personally like blueimp jQuery File Upload Plugin (https://blueimp.github.io/jQuery-File-Upload/)

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

File Upload widget with multiple file selection, drag&drop support, progress bars, validation and preview images, audio and video for jQuery. Supports cross-domain, chunked and resumable file uploads and client-side image resizing. Works with any server-side platform (PHP, Python, Ruby on Rails, Java, Node.js, Go etc.) that supports standard HTML form file uploads.

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

Demos:

演示:

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

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