記錄一下通過瀏覽器下載文件遇到的一些問題
常見后台代碼中,都會將文件名設置在Header中,但就是由此會引發下面的問題:
出於安全原因,瀏覽器禁止調用駐留在當前原點之外的資源,所以前台一直報錯,后來找到了一種解決方式:
controller方法的CORS配置,可以向@RequestMapping注解處理程序方法添加一個@CrossOrigin注解,以便啟用CORS
第一次在后台代碼中沒有加@CrossOrigin("*")注解,導致前台取不到header, 報java Refused to get unsafe header "Content-disposition"這個錯
報這個錯的原因時W3C標准下,不允許調用當前原點之外的資源。
有關@CrossOrigin注解的使用問題,在這篇博客中找到了答案: https://www.cnblogs.com/mmzs/p/9167743.html
加上@CrossOrigin("*")之后,文件還是無法下載,后查閱資料,認識到還應該設置允許訪問的域名等信息,(Access-Control-Expose-Header······)
這點在這片博客中講述的比較清楚,此處不再贅述:http://www.ruanyifeng.com/blog/2016/04/cors.html
@CrossOrigin("*") //
@RequestMapping(value = "/downloadJson",method = RequestMethod.GET)
public String downloadJson(String id, HttpServletResponse response){
boolean result = false;
try {
String info = service.exportInfo(id);
IOUtil.downloadJson(response, model.getTitle(), info);
}catch (Exception e){
e.printStackTrace();
}
return null;
}
public class IOUtil { /** * 導出json格式 * @param response * @param fileName * @param info */ public static void downloadJson(HttpServletResponse response, String fileName, String info) { try { String encodeName = URLEncoder.encode(fileName, StandardCharsets.UTF_8.toString()); response.setCharacterEncoding("utf-8"); /* 設置文件ContentType類型,這樣設置,會自動判斷下載文件類型 */ response.setContentType("application/multipart/form-data"); /* 設置文件頭:最后一個參數是設置下載文件名 */ response.setHeader("Access-Control-Expose-Headers", "Content-Disposition"); //設置允許跨域的key response.setHeader("Content-Disposition", "attachment;filename*=UTF-8''" + encodeName +".json"); /* 用流將數據寫給前端 */ OutputStream os = response.getOutputStream(); os.write(info.getBytes()); os.flush(); os.close(); } catch (Exception e) { e.printStackTrace(); } } /** * 瀏覽器下載文件 * @param file * @param response */ public static void downloadFile(File file, HttpServletResponse response) { InputStream fin = null; ServletOutputStream out = null; try { String fileName = file.getName(); String encodeName = URLEncoder.encode(fileName, StandardCharsets.UTF_8.toString()); fin = new FileInputStream(file); BufferedInputStream bis = new BufferedInputStream(fin); out = response.getOutputStream(); response.setCharacterEncoding("utf-8"); response.setContentType("application/force-download"); response.setHeader("Access-Control-Expose-Headers", "Content-Disposition"); //設置允許跨域的key response.setHeader("Content-Disposition", "attachment;filename=" + encodeName); byte[] buffer = new byte[1024]; int i = bis.read(buffer); while (i != -1) { out.write(buffer, 0, i); i = bis.read(buffer); } out.flush(); response.flushBuffer(); } catch (Exception e) { e.printStackTrace(); } finally { try { if(fin != null) fin.close(); if(out != null) out.close(); } catch (IOException e) { e.printStackTrace(); } } } }
https://www.cnblogs.com/mmzs/p/9167743.html
