问题介绍
Refused to display 'http://xxxxxxxxxxxxx' in a frame because it set 'X-Frame-Options' to 'SAMEORIGIN'.
同样是迁移项目中遇到的问题,具体来源就不说了,说一下场景,我有两个项目,web以及voice。这两个项目,web项目的iframe框架标签,src属性需要嵌入voice项目中jsp,但是在使用过程中,给我报Refused to display 'http://xxxxxxxxxxxxx' in a frame because it set 'X-Frame-Options' to 'SAMEORIGIN'.,无法跨域。
代码是这么写的。
所在的frame标签
<div class="iframe-container">
<iframe id="aiIframe" src="../aiAbility/aiAbility.jsp" frameborder="0"></iframe>
</div>
<div class="copyright"></div>
涉及到这块页面跳转的js,代码没贴全,知道就是iframe标签更改src来跳转的就行,这里跳转的还是本地页面,还没有到外部项目。
$('#aiIframe').attr("src", encodeURI($(obj).attr("data-src") + "?parentName=" + parentName + "&secondParentName=" + secondParentName));
跳转的下一个页面
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<%@ taglib uri="http://www.bonc.com.cn/common/tag/cxt" prefix="cxt" %>
<!DOCTYPE html>
<html>
<head>
<cxt:commonLinks/>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" href="<%=request.getContextPath()%>/css/common.css"/>
<link rel="stylesheet" href="<%=request.getContextPath()%>/css/frame.css"/>
<link rel="stylesheet" href="<%=request.getContextPath()%>/css/aiPowerOpen.css"/>
<link rel="shortcut icon" href="<%=request.getContextPath()%>/images/ico/favicon.ico"/>
<link rel="stylesheet" href="<%=request.getContextPath()%>/css/airita/reset.css">
<script src="<%=request.getContextPath()%>/js/common/common.js"></script>
<script type="text/javascript" src="<%=request.getContextPath()%>/js/echarts4.min.js"></script>
<script type="text/javascript" src="<%=request.getContextPath()%>/js/china.js"></script>
<script type="text/javascript" src="<%=request.getContextPath()%>/js/common/md5.js"></script>
<title>智能调研问卷调研跳转页面</title>
</head>
<body>
<script src="<%=request.getContextPath()%>/pages/jsp/questionnaire/template.js"></script>
</body>
</html>
这个页面所引用的js
$(function () {
//本地nginx地址,响应头在nginx中配置
var url = "http://localhost:8084/AIRITA/yy/pages/jsp/questionnaire/template.jsp";
var tempForm = document.createElement("form");
tempForm.id = "form";
tempForm.name = "form";
document.body.appendChild(tempForm);
console.log(url)
tempForm.action = url;
tempForm.method = "GET";
tempForm.submit();
});
这个url就是远程要跳入的页面地址。
问题分析
既然问题发生在X-FRAME-OPTIONS上,那么了解一下这个东西是什么。
HTTP 配置响应头部 X-Frame-Options_行走的地瓜的博客-CSDN博客_xframeoptions配置
这兄弟的博客解释的也很清楚了,SAMEORIGIN表示该页面可以在相同域名页面的frame中展示。我现在要跨域,肯定不能这么整的,所以我需要将X-FRAME-OPTIONS响应头的数据替换一下。
解决方式
解决方式,因为我连接的是nginx代理来做的,所以我直接在nginx代理中对这个响应头来进行配置了。
location /AIRITA/yy{
proxy_connect_timeout 6000;
proxy_read_timeout 6000;
proxy_send_timeout 6000;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_pass http://172.16.65.108:9012;
proxy_hide_header X-Frame-Options;
add_header X-Frame-Options ALLOWALL;
}
}
proxy_hide_header X-Frame-Options;代表隐藏后端返回过来的X-Frame-Options响应头,因为nginx设置基于add_header X-Frame-Options ALLOWALL响应头,不会覆盖掉原有响应头,而是重新添加一个,报Refused to display 'http://xxxxxxxxxxxxxxxx' in a frame because it set multiple 'X-Frame-Options' headers with conflicting values ('DENY, SAMEORIGIN'). Falling back to 'deny'.
add_header X-Frame-Options ALLOWALL;这个就是设置响应头的方式了。
结论
亲测可用,网上按jsp跨域嵌套jsp找了许久,都没找到合适的。这次也记录一下吧。如果你没用nginx,可以试图改造响应头试一下。这一种我是没有试的,代码也不贴全,毕竟公司代码,怕遇到熟人。希望可以帮助大家吧。