如果ajax=false,文件下载可以正常工作,但是ajaxStatus不会显示。这是因为下载并不是通过ajax请求进行的。
如果ajax=true,将显示ajaxStatus但无法下载!这是因为通过ajax请求无法进行下载。JS/Ajax将成功检索文件,但不知道如何处理它。没有办法用JS强制启动“另存为”对话框。没有办法使用JS访问本地磁盘文件系统(否则将成为巨大的安全漏洞)。
有什么办法让ajaxStatus和fileDownload一起工作?
使用PrimeFaces提供的PrimeFaces.monitorDownload()
JS函数。完整的示例可以在他们自己的<p:fileDownload>
展示页面上找到,以下是该页面的复制内容(特别注意文件下载命令按钮的onclick
属性):
<p:dialog modal="true" widgetVar="statusDialog" header="Status"
draggable="false" closable="false" resizable="false">
<p:graphicImage value="/design/ajaxloadingbar.gif" />
</p:dialog>
<h:form id="form">
<p:commandButton id="downloadLink" value="Download" ajax="false"
onclick="PrimeFaces.monitorDownload(start, stop)"
icon="ui-icon-arrowthichk-s">
<p:fileDownload value="#{fileDownloadController.file}" />
</p:commandButton>
</h:form>
<script type="text/javascript">
function start() {
statusDialog.show();
}
function stop() {
statusDialog.hide();
}
</script>
您可以通过将命令链接更改为以下内容来应用于您的特定情况:
<p:commandLink id="download" value="Download" ajax="false"
onclick="PrimeFaces.monitorDownload(showStatus, hideStatus)"
actionListener="#{zipManager.makeZip()}">
在展示示例中,通过将
<p:ajaxStatus>
替换为简单的
<p:dialog>
来实现。
这一切都是通过一个特殊的 cookie 在幕后进行的,JS 会以短时间间隔轮询它(大约每 100 毫秒)。在创建文件下载响应期间,特殊的 cookie 将被设置在其标头上。一旦文件下载响应标头到达浏览器,那么 cookie 就会在浏览器中设置。当 JS 轮询器在浏览器 cookie 空间中找到它时,它就会关闭进度。