【问题标题】:JS function not triggered with PrimeFaces.monitorDownloadPrimeFaces.monitorDownload 未触发 JS 函数
【发布时间】:2013-12-18 16:36:28
【问题描述】:

我正在使用 Primefaces 4.0 下载文件。我只想在下载完成时触发一个 JS 函数,但似乎不起作用(在 Firefox 和 Google Chrome 中尝试过)。我的测试用例看起来与PF docs 中所做的类似:

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:p="http://primefaces.org/ui">
<h:head />

<h:body>
    <script type="text/javascript">
        function startMessage() {
            alert("Download started!");
        }
        function finishMessage() {
            alert("Download finished!");
        }
    </script>
    <h:form>
        <p:commandButton value="Download" ajax="false"
            icon="ui-icon-arrowreturnthick-1-s"
            onclick="PrimeFaces.monitorDownload(startMessage, finishMessage)">
            <p:fileDownload value="#{bean.file}" />
        </p:commandButton>
    </h:form>
</h:body>
</html>
@ManagedBean
@ViewScoped
public class Bean implements Serializable {

    public StreamedContent getFile() {
        return new DefaultStreamedContent(new ByteArrayInputStream(new byte[0]));
    }

}

下载开始时会触发警报,但下载完成时不会触发。其他人可以试试吗?

【问题讨论】:

  • 同样,我遇到了递归 javascript 错误 Uncaught TypeError: Object function (e,b3){return new bI.fn.init(e,b3,w)} has no method 'cookie' ,这是一个 bug

标签: jsf jsf-2 primefaces


【解决方案1】:

这是一个bug

主要错误在FileDownloadActionListenerorg.primefaces.component.filedownload 包中。

第 65 行

externalContext.addResponseCookie(Constants.DOWNLOAD_COOKIE, "true", Collections.<String, Object>emptyMap());

Constants.DOWNLOAD_COOKIE 是“primefaces.download”,它从未与响应一起发送。

这将导致PrimeFaces.monitorDownload 的Interval 永远不会调用停止函数,因为cookie 永远不会被写入。

【讨论】:

  • 如果您需要使用自定义解决方案下载,您还需要在自定义下载操作中进行此操作。
【解决方案2】:

我遇到了同样的问题,发现它与创建的 cookie 的 'path' 属性有关。

我的应用上下文路径的格式为 'http://host/a/b/c',因此在服务器中,cookie 是使用 'default' 创建的em> 路径为 '/a/b/c',但在浏览器中我发现在 JavaScript 执行期间检索到的 cookie 只是那些带有路径的'/a' (Chrome) 或 '/a/' (Firefox)。因此,即使在创建 'primefaces.download' cookie 时,客户端中的 JavaScript 也不会为应用程序检索它。

我所要做的就是在发送响应之前'覆盖' cookie 创建(即创建第二个具有浏览器期望的正确路径的 cookie):

   ...
   FacesContext facesContext = FacesContext.getCurrentInstance();
   ExternalContext externalContext = facesContext.getExternalContext();
   Map<String, Object> map = new HashMap<String, Object>();
   map.put("path", "/a/");
   externalContext.addResponseCookie(Constants.DOWNLOAD_COOKIE, "true", map);
   ...

另外,我注意到 PrimeFaces.monitorDownload() 的默认实现尝试'clean' 'primefaces.download' cookie 只需将其值设置为 'null',但由于 Chrome 和 Firefox 处理 cookie 的方式不同(将最后一个 '/' 字符附加到Firefox 中的当前路径)我最好在 'override' 执行结束函数后清理 cookie 的 JS 代码:

   ...    
   document.cookie = 'primefaces.download=; path=/a/; expires=Thu, 01 Jan 1970 00:00:00 UTC';
   ...

这样我可以确保在下一次执行中,cookie 将不会出现在客户端中,直到它再次在服务器中创建。

【讨论】:

  • 尚未测试,但似乎是一个聪明的解决方法;-)
  • 非常感谢。这对我有用。我还必须设置文件路径。我正在使用 PrimeFaces 6.1
  • 感谢 Xtreme Biker 的评论 :)
  • 这些是好消息 wolf97084,很高兴知道它也对你有用
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-06-15
  • 2023-04-01
  • 2021-05-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多