我正在使用 Primefaces 4.0 进行文件下载。我只想在下载完成时触发JS功能,但似乎无法工作(在Firefox和谷歌浏览器中尝试过)。我的测试用例看起来类似于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]));
}
}
下载开始时会触发警报,但下载完成后则不会触发警报。其他人可以尝试一下吗?
答案 0 :(得分:8)
这是一个bug。
主要错误在FileDownloadActionListener
org.primefaces.component.filedownload
包中。
第65行
externalContext.addResponseCookie(Constants.DOWNLOAD_COOKIE, "true", Collections.<String, Object>emptyMap());
Constants.DOWNLOAD_COOKIE
是“primefaces.download”,它永远不会随着回复一起发送。
这会导致PrimeFaces.monitorDownload
的Interval永远不会调用stop函数,因为cookie永远不会被写入。
答案 1 :(得分:2)
我遇到了同样的问题,发现它与创建的Cookie的 '路径' 属性有关。
我的应用上下文路径的格式为 'http://host/a/b/c' ,因此在服务器中使用 'default'创建Cookie 路径为 '/ 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()
的默认实施尝试'清理' 'primefaces.download' Cookie只需将其值设置为'null',但由于Chrome和Firefox处理Cookie的方式不同(添加最后的'/'字符到Firefox中的当前路径)我最好还'覆盖'也是执行结束函数时清理cookie的JS代码:
...
document.cookie = 'primefaces.download=; path=/a/; expires=Thu, 01 Jan 1970 00:00:00 UTC';
...
这样我确保在下一次执行中,cookie在客户端中根本不存在,直到它再次在服务器中创建。