记录一下通过浏览器下载文件遇到的一些问题
常见后台代码中,都会将文件名设置在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