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错误依旧,无法上传第二个文件。

有什么想法吗?


编辑以防万一:我不知道为什么,但在对话框中选择要上传的文件后,&lt;iframe&gt; 以某种方式添加到我的页面。


编辑 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?

jsf spring安全访问被拒绝认证登录

如何在 JSF 中保存上传的文件

JSF拒绝处理深层嵌套的复合组件。不,真的:“JSF1098:[...]这浪费了处理器时间[...]”

JSF 2.2 h:命令按钮触发后的输入文件更新页面