跨域问题
目的:记录下对跨域请求的认识
漫谈(仅个人的理解,不一定正确)
HTTP请求是无状态的请求,只要你通过服务端的验证一般都会得到期望的响应结果。即你通过自己写HTTP请求,自己处理HTTP的响应是不会存在跨域的问题。
但是浏览器的同源策略,是让你无法获取到跨域服务端的响应数据。
首先Http请求是用户触发的,所以当浏览器发出一个Http请求会判断该请求的资源是否跨域,如果没有跨域一般情况下http的请求头不会添加origin属性,请求的服务器会处理请求并响应,浏览器渲染响应数据。
如果是跨域请求资源,浏览器会在请求头上添加origin属性值,表示该请求所处的域。被跨域请求的服务器接收到该http请求,如果该服务器允许该跨域请求访问的资源,则会处理该请求,同时服务端需要在响应头中添加Access-Control-Allow-Orign属性值告诉浏览器允许该域的请求。浏览器通过检查响应头的Access-Control-Allow-Orign的属性值判断是否是允许跨域请求该资源,如果允许则渲染响应数据。
更新
@ResponseBody
@RequestMapping(value = "/export", method = RequestMethod.GET)
public void export(HttpServletResponse response) {
try {
Workbook workbook = getWorkbook();
OutputStream out = null;
out = response.getOutputStream();
Collection<String> headerNames = response.getHeaderNames();
System.out.println("--------------- GET Before -------------------");
for (String hn : headerNames) {
System.out.println(hn + ":" + response.getHeader(hn));
}
response.reset();// 清空输出流 清空输出流会重置Filter中的response中添加的响应头,导致出现跨域问题
response.setHeader("Content-disposition", "attachment;filename=" + DateUtils.getDate("yyyy-MM-dd") + ".xlsx");// 设定输出文件头
response.setContentType("application/vnd.ms-excel;charset=UTF-8");// 定义输出类型
response.setHeader("Access-Control-Allow-Origin", "*");
workbook.write(out);
} catch (Exception e) {
logger.error("下载:", e);
} finally {
Collection<String> headerNames = response.getHeaderNames();
System.out.println("--------------- GET AFTER -------------------");
for (String hn : headerNames) {
System.out.println(hn + ":" + response.getHeader(hn));
}
}
}
/**
* 阮一峰的博客对跨域问题讲的比较通透
* http://www.ruanyifeng.com/blog/2016/04/same-origin-policy.html
* http://www.ruanyifeng.com/blog/2016/04/cors.html
*/
response.reset();重置响应流前后响应头的区别打印
以下是他人写的比较详细的文章
https://www.cnblogs.com/dojo-lzz/p/4265637.html
https://www.jianshu.com/p/89a377c52b48
https://www.cnblogs.com/relucent/p/4274158.html