解決下載ftp文件過程中,瀏覽器直接解析文件(txt,png等)的問題
阿新 • • 發佈:2018-07-11
filename map 需要 etc home 3.0.0 var att esp
搭建了一個ftp服務器,供用戶進行上傳下載,在下載過程中發現,一些文件,例如txt,jpg,png,pdf等直接被瀏覽器解析了。在瀏覽器中顯示其內容,沒有下載。
下面通過網上查詢得到一些解決方法:
1:修改ftp目錄下的.htacess文件,這個文件主要做一些類型映射,使各個文件類型映射為 octet-stream 類型,這樣瀏覽器就不能解析了。
但是,我沒有在ftp目錄下發現該文件,通過filezilla連接服務器, filezilla>服務器>強制顯示隱藏文件 ,也沒有發現該文件。聽說該文件是apache獨有的,我用的是vsftpd服務器,不知道是否存在不一致,於是放棄。
2:第二種方法
使用ajax請求,將文件輸出流(OutputStream)作為回調結果返回。
html代碼, 後臺代碼同第4中方法。
<!DOCTYPE html> <html lang="en"> <head> <script type="text/javascript" src="/js/jquery-3.0.0.min.js"></script> <meta charset="UTF-8"> <title>Title</title> <script> function link() { $.ajax({ type: "get", //請求方式 url: "downloadFileByOutputStream", //請求路徑 data: { "filename":‘homepage.png‘ //請求參數 }, async: true, //異步,(同步已經廢棄,會報錯)。 success:function (flag) { //請求成功,flag返回數據 if (flag != "") { console.log(flag); //瀏覽器控制臺打印數據 var obj = eval(flag); //對數據進行轉換 localStorage[‘UsertypeSelect‘]=JSON.stringify(obj); //將返回的數據存儲到本地。 }; } }); } </script> </head> <body> <a href="javascript:void(0)" onclick="link()">客戶端下載OutputStream</a> //調用上面的函數 </body> </html>
調用之後,發現數據亂碼, eval(flag)對返回數據轉化失敗。
3: 使結果作為PrintWriter流作為回調結果,使用隱藏表單提交的方式對流進行回調。結果 txt,doc等字符文件能夠下載,但是圖片等字節文件不能下載。
前端代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script type="text/javascript" src="/js/jquery-3.0.0.min.js"></script> <script> function download(){ console.log(‘執行‘); downloadTemplate(‘/downloadFileByPrintWriter‘, ‘filename‘, ‘homepage.png‘); } function downloadTemplate(action, type, value){ //action 請求接口, type : 後臺接口需要的參數名,value 請求的參數值 console.log(action); var form = document.createElement(‘form‘); //創建表單 document.body.appendChild(form); form.style.display = "none"; form.action = action; //接口 form.id = ‘download‘; //表單id form.method = ‘post‘; //請求方式 var newElement = document.createElement("input"); //創建元素,類型為input newElement.setAttribute("type","hidden"); //隱藏 newElement.name = type; //元素名為type newElement.value = value; //元素值 value form.appendChild(newElement); form.submit(); //提交 } </script> </head> <body> <span onclick="download()">客戶端下載PrintWriter</span> </body> </html>
後臺代碼:
/** * 根據給定的文件名進行下載 * Description: 從FTP服務器下載文件 * @param filename 要下載的文件名 * @return */ @RequestMapping("/downloadFileByPrintWriter") @ResponseBody public String downloadFileByPrintWriter(HttpServletResponse response, String filename) throws IOException { FTPClient ftp = new FTPClient(); try { int reply; ftp.connect(host, port); ftp.login(username, password);// 登錄 ftp.enterLocalPassiveMode(); //將ftp設置為被動模式。否則不成功。 reply = ftp.getReplyCode(); if (!FTPReply.isPositiveCompletion(reply)) { ftp.disconnect(); return "ftp無連接"; } ftp.changeWorkingDirectory(publicFilePath);// 轉移到FTP服務器目錄 logger.debug("遠程路徑" + publicFilePath); FTPFile[] fs = ftp.listFiles(); for (FTPFile ff : fs) { logger.debug("遠程文件名" + ff.getName()); if (ff.getName().equals(filename)) { InputStream in = ftp.retrieveFileStream(ff.getName()); //讀取ftp服務器文件,返回輸入流 int len = 0; byte[] buff = new byte[1024]; response.reset(); //重置響應 response.setContentType("application/octet-stream"); //設置響應類型為流類型 response.addHeader("Content-Disposition", "attachment; filename=\"" + filename + "\""); //文件名 InputStreamReader inputStreamReader = new InputStreamReader(in); PrintWriter fw = response.getWriter(); //得到response的字符打印流 //創建一個rd的字符留緩沖區,將字符裝載入緩沖區中 BufferedReader bf = new BufferedReader(inputStreamReader); char[] chs = new char[1024]; // while ((len = bf.read(chs)) != 0) { // logger.debug("向fw寫入"); //// fw.write(chs, 0, len); // } String str=null; while ((str = bf.readLine()) != null) { fw.write(str); //將ftp輸入流寫出到printWriter fw.flush(); } fw.flush(); in.close(); fw.close(); return "成功"; } } ftp.logout(); } catch (IOException e) { e.printStackTrace(); } finally { if (ftp.isConnected()) { try { ftp.disconnect(); } catch (IOException ioe) { } } } return "下載失敗"; }
4:將文件作為OutputStream流作為回調結果,使用隱藏表單提交的方式對流進行回調。成功
html代碼
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script type="text/javascript" src="/js/jquery-3.0.0.min.js"></script> <script> function download(){ console.log(‘執行‘); downloadTemplate(‘/downloadFileByOutputStream‘, ‘filename‘, ‘homepage.png‘); } function downloadTemplate(action, type, value){ console.log(action); var form = document.createElement(‘form‘); document.body.appendChild(form); form.style.display = "none"; form.action = action; form.id = ‘download‘; form.method = ‘post‘; var newElement = document.createElement("input"); newElement.setAttribute("type","hidden"); newElement.name = type; newElement.value = value; form.appendChild(newElement); form.submit(); } </script> </head> <body> <span onclick="download()">客戶端下載PrintWriter</span> </body> </html>
後臺代碼:
/** * 根據給定的文件名進行下載 * Description: 從FTP服務器下載文件 * @param filename 要下載的文件名 * @return */ @RequestMapping("/downloadFileByOutputStream") @ResponseBody public String downloadFileByOutputStream(HttpServletResponse response, String filename) throws IOException { logger.debug("下載ByOutputStream"); FTPClient ftp = new FTPClient(); try { int reply; ftp.connect(host, port); // 如果采用默認端口,可以使用ftp.connect(host)的方式直接連接FTP服務器 ftp.login(username, password);// 登錄 ftp.enterLocalPassiveMode(); //將ftp設置為被動模式。否則不成功。 reply = ftp.getReplyCode(); if (!FTPReply.isPositiveCompletion(reply)) { ftp.disconnect(); return "連接失敗"; } ftp.changeWorkingDirectory(publicFilePath);// 轉移到FTP服務器目錄 logger.debug("遠程路徑" + publicFilePath); FTPFile[] fs = ftp.listFiles(); for (FTPFile ff : fs) { logger.debug("遠程文件名" + ff.getName()); if (ff.getName().equals(filename)) { InputStream in = ftp.retrieveFileStream(ff.getName()); logger.debug(in.toString()); int len = 0; byte[] buff = new byte[1024*1024]; response.reset(); response.setContentType("application/octet-stream"); //Name the file response.addHeader("Content-Disposition", "attachment; filename=\"" + filename + "\""); // response.addHeader("Content-Length", out..ToString()); OutputStream out=response.getOutputStream(); //響應輸出字節流 // OutputStream out = new PipedOutputStream(); while((len=in.read(buff))!=-1){ logger.debug("以字節流形式寫出OutPutStream"); out.write(buff, 0, len); out.flush(); } in.close(); out.close(); return "成功"; } } ftp.logout(); } catch (IOException e) { e.printStackTrace(); } finally { if (ftp.isConnected()) { try { ftp.disconnect(); } catch (IOException ioe) { } } } return "失敗"; }
解決下載ftp文件過程中,瀏覽器直接解析文件(txt,png等)的問題