JSF inputFile 拒绝在框架中显示“mypage.xhtml”,因为它将“X-Frame-Options”设置为“拒绝”
Posted
技术标签:
【中文标题】JSF inputFile 拒绝在框架中显示“mypage.xhtml”,因为它将“X-Frame-Options”设置为“拒绝”【英文标题】:JSF inputFile Refused to display 'mypage.xhtml' in a frame because it set 'X-Frame-Options' to 'deny' 【发布时间】:2020-05-21 23:49:31 【问题描述】:我正在关注this answer by BalusC 尝试将文件上传到服务器。我按原样使用他的代码。
在使用 JSF 2.2 时,从未到达过 #bean.save
,并且从未保存过文件。
服务器的控制台什么也没显示。但是js控制台显示这个错误:
Refused to display 'http://localhost:8080/my_app/hello.xhtml' in a frame because it set 'X-Frame-Options' to 'deny'.
jsf.js.xhtml?ln=javax.faces:1 Uncaught DOMException: Blocked a frame with origin "http://localhost:8080" from accessing a cross-origin frame.
at FrameTransport.callback (http://localhost:8080/my_app/javax.faces.resource/jsf.js.xhtml?ln=javax.faces:1:5109)
at HTMLIFrameElement.<anonymous> (http://localhost:8080/my_app/javax.faces.resource/jsf.js.xhtml?ln=javax.faces:1:5759)
我看到this answer 表明这是 JSF 2.2 中的一个错误。于是我上传到了2.3。
在 JSF 2.3 中,达到了#bean.save
,并且成功保存了文件。但是js错误依旧,无法上传第二个文件。
有什么想法吗?
编辑以防万一:我不知道为什么,但在对话框中选择要上传的文件后,<iframe>
以某种方式添加到我的页面。
编辑 2
BalusC 和 Selaron 建议我尝试将 X-Frame-Options 标头更改为不“拒绝”。我尝试添加一个@WebFilter
并在那里设置标题,如下所示:
public void doFilter(...)
HttpServletResponse response = (HttpServletResponse) res;
response.addHeader("X-Frame-Options", "sameorigin");
response.setHeader("MyHeader", "whatever");
chain.doFilter(req, res);
我添加了第二个标头 MyHeader,其值为“whatever”,以检查在访问浏览器时响应是否包含该标头。
事实证明 MyHeader 可以正确访问浏览器,但 X-Frame-Options 仍然保持为“拒绝”。
当我使用 Spring Security 时,我想可能有其他过滤器干扰了我的响应?
所以,我有这个:
@Configuration
@EnableWebSecurity
public class BasicConfiguration extends WebSecurityConfigurerAdapter
@Override
protected void configure(HttpSecurity http) throws Exception
...
http.addFilterAfter(
new CustomFilter(), SwitchUserFilter.class);
...
我的CustomFilter
与我之前展示的一样工作:MyHeader 仍然存在,但 X-Frame-Options 没有。
我在SwitchUserFilter
之后添加了它,因为HttpSecurity.addFilter
的文档说这是链中的最后一个过滤器。
我现在有点迷茫。我的几个问题:
我是否可以假设 X-Frame-Options 标头被其他过滤器覆盖?
如何确保我设置的 X-Frame-Options 保留?或者,我怎样才能将过滤器放在链的末尾?
【问题讨论】:
该错误提示您的应用或服务器返回X-Frame-Options:deny
响应标头。这是真的?关闭它并重试。在旧版浏览器中,基于 Ajax 的文件上传只能通过 iframe 进行。
嗨@BalusC。我在设置标题时遇到了一些麻烦。我正在更新我的问题
实际上,在技术层面上,您有一个新问题。 1:不是说,也可以是反向代理,负载均衡器等。 2:通过使用 *** 中其他现有 Q/A 中描述的可用机制
2:第一部分:通过检查其他系统是否覆盖它(甚至可以是浏览器插件)
如果过滤器不起作用,请参阅 ***.com/questions/27358966/… 了解“代理”内容
【参考方案1】:
我在 Mojarra 团队计划 Implement "ajax" file upload #2577 和 commit actually implementing it to the jsf javascript 时发现了这个问题。 疯狂地无法再访问有关问题 2577 的文档,因此它没有解释为什么这里需要 iframe 的背景。
this blog的第一段简要解释了为什么AJAX文件上传是/曾经(?)不能直接:
使用隐藏 iFrame 上传 Ajax 样式文件 作者:Viral Patel · 2008 年 11 月 18 日
无法使用 AJAX 上传文件。 AJAX 实际上并没有发布 表单到服务器,它将选定的数据以表单发送到服务器 POST 或 GET 请求。由于 javascript 无法抓取 文件从用户机器发送到服务器,它只是 AJAX 是不可能的。您必须求助于常规的旧表单提交。 如果您在某处读过/看过它,那么它不是通过 AJAX。文件 在这种情况下,通过 iframe 进行上传。你必须使用一个 iframe 上传文件。所以,你可以使用 iframe 来异步 上传(类似于 AJAX,但不是 AJAX)。
所以最后你的选择是——正如 BalusC 评论的那样——放松你的 X-Frame-Options
标头设置或将你的上传更改为不使用 AJAX:
<h:form enctype="multipart/form-data">
<h:inputFile value="#bean.file" />
<h:commandButton value="upload" action="#bean.save"/>
</h:form>
【讨论】:
您没有 ajax 的解决方案有效。我会继续尝试ajax方式,如果没有任何效果我会接受答案以上是关于JSF inputFile 拒绝在框架中显示“mypage.xhtml”,因为它将“X-Frame-Options”设置为“拒绝”的主要内容,如果未能解决你的问题,请参考以下文章
JSF 2.2 h:inputFile 不适用于漂亮的面孔[重复]
哪种方法用于将动作回调绑定到 JSF/ICEFaces InputFile?