【问题标题】:JSF inputFile Refused to display 'mypage.xhtml' in a frame because it set 'X-Frame-Options' to 'deny'JSF inputFile 拒绝在框架中显示“mypage.xhtml”,因为它将“X-Frame-Options”设置为“拒绝”
【发布时间】: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 的文档说这是链中的最后一个过滤器。

我现在有点迷茫。我的几个问题:

  1. 我是否可以假设 X-Frame-Options 标头被其他过滤器覆盖?

  2. 如何确保我设置的 X-Frame-Options 保留?或者,我怎样才能将过滤器放在链的末尾?

【问题讨论】:

  • 该错误提示您的应用或服务器返回X-Frame-Options:deny 响应标头。这是真的?关闭它并重试。在旧版浏览器中,基于 Ajax 的文件上传只能通过 iframe 进行。
  • 嗨@BalusC。我在设置标题时遇到了一些麻烦。我正在更新我的问题
  • 实际上,在技术层面上,您有一个新问题。 1:不是说,也可以是反向代理,负载均衡器等。 2:通过使用 Stackoverflow 中其他现有 Q/A 中描述的可用机制
  • 2:第一部分:通过检查其他系统是否覆盖它(甚至可以是浏览器插件)
  • 如果过滤器不起作用,请参阅 stackoverflow.com/questions/27358966/… 了解“代理”内容

标签: jsf jsf-2.2


【解决方案1】:

我在 Mojarra 团队计划 Implement "ajax" file upload #2577commit 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方式,如果没有任何效果我会接受答案
猜你喜欢
  • 2019-03-09
  • 2022-07-18
  • 1970-01-01
  • 2020-03-10
  • 2020-05-07
  • 2017-11-17
  • 2013-12-28
相关资源
最近更新 更多