如何将meta标签作为该部分中的第一个?

时间:2011-07-28 14:36:52

标签: jsf internet-explorer-9 primefaces

我正在使用JSF2,GlassFish 3.1,PrimeFaces 2.x.

我在IE9上遇到奇怪的渲染问题。我应该能够通过插入以下内容强制IE9呈现为IE9:

<html>
<head>
  <!-- Enable IE9 Standards mode -->
  <meta http-equiv="X-UA-Compatible" content="IE=9" />
...

但事实是,它不起作用,因为(我被告知)元标记必须是该部分中的第一个标记。

当我在我的XHTML文件中执行此操作时...

<html ...>

<f:view contentType="text/html" locale="#{loginHandler.currentLocale}">

<h:head>
    <!-- Enable IE9 Standards mode -->
    <meta http-equiv="X-UA-Compatible" content="IE=9" />

生成的HTML看起来像这样,其中JSF / PrimeFaces在我的新元标记之前插入了一堆“链接”和“脚本”标记。

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<link type="text/css" rel="stylesheet" href="/orcf-webui/javax.faces.resource/jquery/ui/jquery-ui.css.jsf?ln=primefaces&amp;v=2.2" />
<link type="text/css" rel="stylesheet" href="/orcf-webui/javax.faces.resource/wijmo/wijmo.css.jsf?ln=primefaces&amp;v=2.2" />
<script type="text/javascript" src="/orcf-webui/javax.faces.resource/jquery/jquery.js.jsf?ln=primefaces&amp;v=2.2"></script>
<script type="text/javascript" src="/orcf-webui/javax.faces.resource/jquery/ui/jquery-ui.js.jsf?ln=primefaces&amp;v=2.2"></script>
<!-- Enable IE9 Standards mode -->
<meta http-equiv="X-UA-Compatible" content="IE=9" />

有没有办法让我的元标记在正确的位置,以便它可以工作? (或者让IE9问题消失的另一种方法是什么?

5 个答案:

答案 0 :(得分:27)

  1. 元标记必须在之前所有PrimeFaces内容: http://blogs.msdn.com/b/cjacks/archive/2012/02/29/using-x-ua-compatible-to-create-durable-enterprise-web-applications.aspx

  2. HTTP标头和HTML HEAD完全不同。

  3. 在PrimeFaces 3.0中,新的 facet 已添加到h:headhttp://blog.primefaces.org/?p=1433 所以解决方案是:

  4. <h:head>
        <f:facet name="first">
            <meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1" />
        </f:facet>
    </h:head>
    

答案 1 :(得分:14)

我认为最好的解决方案是创建JSF PhaseListener,它将X-UA-Compatible标头添加到HTTP响应中

public class UACompatibleHeaderPhaseListener implements PhaseListener {
    private static final long serialVersionUID = 1L;

    @Override
    public PhaseId getPhaseId() {
        return PhaseId.RENDER_RESPONSE;
    }

    @Override
    public void beforePhase(PhaseEvent event) {
        final FacesContext facesContext = event.getFacesContext();
        final HttpServletResponse response = (HttpServletResponse) facesContext.getExternalContext().getResponse();
        response.addHeader("X-UA-Compatible", "IE=edge");
    }

    @Override
    public void afterPhase(PhaseEvent event) {
    }

}

并将其注册到faces-config.xml

<faces-config xmlns="http://java.sun.com/xml/ns/javaee" version="2.0">
  <lifecycle>
    <phase-listener>com.example.UACompatibleHeaderPhaseListener</phase-listener>
  </lifecycle>
</faces-config>

另一个选择是创建servlet Filter并在web.xml中注册它。

为什么需要这个?

  1. 想象一下,您的Web应用程序部署在IE兼容性列表中的域(或子域)上:http://ie9cvlist.ie.microsoft.com/ie9CompatViewList.xml因此您需要使用X-UA-Compatible标头将IE切换回最新模式。

  2. 想象一下,您的Web应用程序部署在WebLogic服务器上(使用mojarra 2.0.4),因此您无法更改JSF实现。

答案 2 :(得分:3)

您可以创建添加标题的Filter

X-UA-Compatible: IE=9

回应对象。

Source

答案 3 :(得分:2)

您可能想要从Mojarra切换到MyFaces。查看MyFaces' HEAD renderer的源代码 - 首先获取元素的内容,然后呈现其他资源。 Mojarra可能正在这样做。如果您不想切换JSF实现,则可以实现自己的HEAD元素渲染器。

但是我建议只是找出为什么IE9在没有 X-UA-Compatible 元标记的情况下无法正常工作。它应该使更新的版本像旧版本一样。

答案 4 :(得分:2)

只是评论你的答案和之前的评论:

如果你在IE8上查看diagram here所示的页面,那么

HTTP标题和HTML标题并不完全不同(有效)。如果设置HTTP标头,而不是HTML Head,则仍会考虑来自HTTP标头的指令。

我不知道IE9的行为如何,但我想以类似的方式。