2015-04-15 60 views
50

我想上傳(單個)文件到服務器並顯示上傳進度。在現代瀏覽器中上傳文件的最佳方式是什麼

我知道我可以使用HTTP POST上傳文件。我不熟悉網絡套接字,但據我所知,二進制數據也可以這樣發送,因爲websockets是雙向的,我可以獲得上傳的進度。

我並不擔心舊版瀏覽器,所以iframe和flash解決方案並不很吸引人,除非在實現該路線方面有顯着的優勢。

我也很好奇最好的服務器端技術。他們的優勢是使用像Django這樣的wsgi服務器嗎?或者,也許非阻塞I/O技術,如Node.js?我不問,如果Web框架x比Web框架y好,或者服務器x比服務器y好。但是,簡單來說,理想的技術應該具有什麼功能,以便在客戶端上傳設備。

更新這似乎是服務器端沒有軸承的技術/ API的使用在客戶端上,以方便上傳。

+2

爲了誰投票決定關閉我的問題,爲什麼會偏離主題的人嗎?我有一個特定的編程問題,這是可以回答的......許多其他人都問過這個問題,但隨着瀏覽器技術的發展,這個問題的答案可能會改變。 – Tom

+0

vtortola的答案是處理你所要求的...使用HTML5 File API的最佳方式。服務器端取決於你。無論哪種平臺最適合您的整體需求。只使用任何一個平臺來上傳文件是沒有任何優勢的。 (我不是那些投棄權票的人,只是覺得這是比評論更多的評論) – dgraves

+0

我刪除了關於服務器端技術的一點。因爲這可能是基於意見的,並且似乎並不影響客戶端選項以促進上傳。 – Tom

回答

52

編輯(2017-10-17):截至目前,還可以選擇使用Fetch API。它提供了與更現代的基於承諾的API背後的XMLHttpRequest基本相同的功能。對於本地不支持window.fetch()的瀏覽器有一個polyfill(現在主要是Internet Explorer和較早的Safari版本)。

XMLHttpRequest的與Web插座與別的東西

顯然XMLHttpRequest。它在現代瀏覽器中的功能非常龐大,涵蓋了幾乎所有場景。它會產生一個標準的POST或PUT請求,任何Web服務器和框架組合都可以處理。

雖然網絡套接字對於某些場景很好,但它是一種不同的協議,增加了很多複雜性 - 如果您需要來自服務器的實時響應,它們只值得使用。正如你注意到的那樣,像Flash這樣的其他方法只是醜陋的黑客。

發送二進制數據

通常情況下,您將不能直接訪問文件。因此,您的頁面上某處會有一個<input type="file">表單字段,並等待用戶選擇一個文件。然後選項爲:

  • 僅發送文件內容:request.send(input.files[0])。請求主體將是文件的內容,不會執行任何編碼,也不會傳輸文件名等元數據。 Browser compatibility:Chrome 7,Firefox 3.6,Opera 12,IE 10.
  • Sending the data of the entire formrequest.send(new FormData(input.form))。這裏的表單內容將被編碼爲multipart/form-data,這意味着您可以發送多個表單字段,元數據如字段和文件名也會被傳送。在發送之前,您也可以使用modify the FormData object。根據服務器端框架的不同,處理這個請求可能比原始數據更簡單,通常有很多助手可以使用。 Browser compatibility:Chrome 6,Firefox 4,Opera 12,IE 10.
  • Sending a typed array:以防萬一您沒有文件,但只想發送一些即時生成的二進制數據。這裏沒有執行額外的編碼,因此就服務器端而言,這起作用就像發送文件內容一樣。 Browser compatibility:9的Chrome,火狐9,歌劇11.60,IE 10

顯示上傳進度

你可以listen to progress events on XMLHttpRequest.upload。​​有loadedtotal屬性,可以確定您的請求有多遠。 Browser compatibility:鍍鉻7,火狐3.5,歌劇11.60,IE 10

JavaScript庫

有包裝這裏列出的功能當然現有的庫。這些都在其他答案中提到,在網上搜索肯定會變得更多。我明確地不想在這裏提出任何圖書館 - 他們哪一個(如果有的話)應該是純粹的偏好問題。

+0

我也許應該提到的是,你可以很容易地通過'xhr.send(inpFile.files [0])發送二進制(或文本)文件;'你也可以_.send()_整體形式,沒有必要與FORMDATA打擾,除非你需要動態的東西。 – dandavis

+0

@dandavis:你是對的,我只是忘記了文件是blob。我相應地改變了我的答案,然而它變得太長了。 –

3

文件可以通過AJAX上傳。使用jQuery form plugin。它完成將文件綁定到表單並將其序列化的所有骯髒工作。它也能夠顯示上傳進度。

服務器堆棧與它沒有太大的關係。

Demo

4

我個人很喜歡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

17

我的答案是比較晚,但這裏有雲:


簡短的回答:

的XMLHttpRequest是在現代上傳文件的最好方法瀏覽器。



什麼是XMLHttpRequest的?

JavaScript XMLHttpRequest是由Microsoft設計由Mozilla,蘋果和谷歌採取了對象。它現在是standardized in the W3C。它提供了一種簡單的方法來檢索一個URL的數據,而不必做一個全面刷新頁面。一個Web頁面可以在不中斷用戶正在做更新只是一個頁面的一部分。 XMLHttpRequest的是AJAX節目大量使用。

儘管它的名字,XMLHttpRequest的可用於檢索任何類型的數據,而不僅僅是XML的,它支持比HTTP(包括文件和FTP )等協議。

XMLHttpRequest對象已經變得在Html5的規範的換裝。具體的XMLHttpRequest Level 2


優點:

  • 字節流,例如文件斑點上載FORMDATA對象的處理和下載
  • 進度事件上傳和下載
  • 期間
  • Cro SS-起源請求
  • 允許使得匿名請求 - 未發送HTTP引用
  • 設置超時的請求
  • 上傳在背景
  • 的發生的能力用戶所在的頁面保持不變
  • 不需要對服務器端進行任何更改 ,所以現有的服務器端邏輯應該保持不變,這使得這種技術更容易適應。

HTML5的進度事件:

按照該Html5 Progress Events spec,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. Mime類型

有關可以提供給用戶的文件信息完成百分比的進度條

  • 上傳速度或上傳帶寬
  • 剩餘
  • 中的字節的近似時間上傳迄今
  • 使用XMLHttpRequest的演示

    服務器側


  • 文件上載的響應請以「Uploading files using Html5 with Progress indication demo」爲例。所有需要的JavaScript代碼都在頁面中,但沒有包含CSS。出於安全原因,文件類型僅限於jpg,png,gif和txt。最大文件大小是2MB。


    XMLHttpRequest的瀏覽器兼容性:

    XMLHttpRequest Browser compatibility


    相關問題