1. 程式人生 > >Spring MVC 檔案下載IE瀏覽器不支援的問題解決

Spring MVC 檔案下載IE瀏覽器不支援的問題解決

  今天碰到一個比較奇怪的技術問題,使用Spring MVC做檔案下載時,FireFox、Chrome瀏覽器下載都沒有遇到問題,IE 11卻不能正常下載,總是提示“可能已刪除或移動檔案”。大家都說是IE瀏覽器不支援HTTP CREATED(201)狀態碼,但事實上我返回的是HTTP OK(200)狀態碼,但問題依然得不到解決,因此引起此問題的原因跟這個HTTP狀態碼是無關的。

  

  看看下載到的檔案,檔案其實已經下載下來了,只不過其副檔名為“.w2s1z41.partial”,將副檔名去掉,得到的是一個zip檔案,該zip檔案可以正常解壓縮。因此斷定,檔案已全部下載完成。

  

  再來看看服務端的問題程式碼(針對IE不能正常下載,其他瀏覽器正常):

/**
 * 客戶端軟體的更新下載
 * @return
 * @throws HttpErrorException 
 */
@RequestMapping(value="/client/update", method=RequestMethod.GET)
public ResponseEntity<byte[]> update() throws HttpErrorException {	
	String zipFile = "E:\\proj-svn-local\\tmp\\PPMS-Client-Setup_x86_1.0.35.zip";
	File downloadZip = new File(zipFile);
		
	HttpHeaders headers = new HttpHeaders();
	headers.setContentDispositionFormData("attachment", downloadZip.getName());
	headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
		
	ResponseEntity<byte[]> responseEntity;
	try {
		responseEntity = new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(downloadZip), headers, HttpStatus.OK);
	} catch (IOException e) {
		modelMsg = "Read zip file error: " + downloadZip.getPath();;
		throw new HttpErrorException(modelMsg, HttpStatus.INTERNAL_SERVER_ERROR.value());
	}
		
	return responseEntity;
}

  經過多番除錯,最終發現問題的所在,原來問題出在下面這行上:

headers.setContentDispositionFormData("attachment", downloadZip.getName());

  這行程式碼的作用是用於告訴瀏覽器如何顯示本次請求響應所附加的檔案,“attachment”表示是讓瀏覽器以下載附件的形式開啟檔案。按道理,這也沒錯。通過除錯打印出其設定內容,得到文字如下:

[form-data; name="attachment"; filename="PPMS-Client-Setup_x86_1.0.35.zip"]

  問題出現了,前面出現了“form-data”字元,此標識應該是在檔案上傳時才使用(上傳檔案時一般都將檔案放置在表單域中),而當前要做的是“檔案下載”,這樣不出問題才怪啊。取而代之的headers.set方法,而非headers.setContentDispositionFormData()方法,所以將問題行程式碼更換成下述程式碼,問題便可得到解決:

headers.set(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + downloadZip.getName() + "\"");