跨域问题

目的:记录下对跨域请求的认识

漫谈(仅个人的理解,不一定正确)

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

posted @ 2019-12-18 16:39  kayj  阅读(226)  评论(0编辑  收藏  举报