steps to reproduce
- open chrome to simulate iPad with dev tool
- run the code below:
<zk> <button label="Download " onClick="download()"> </button> <zscript><![CDATA[ import org.apache.poi.util.*; public void download() throws java.io.IOException{ org.zkoss.zul.Filedownload.save(IOUtils.toByteArray(support.issue.IssueVM.class.getResourceAsStream("test.pdf")), "application/pdf", "test.pdf"); } ]]> </zscript> </zk> You can replace the file with any file path
- click the button to download a file
result
root cause
f (zk.mobile) { zAu.cmd0.download = function (url) { if (url) { var link = document.createElement('a'), evt = document.createEvent('Event'); link.id = 'zk_download'; link.href = url; if (!(zk.ios >= 7)) link.target = '_blank'; evt.initEvent('click', true, false); link.dispatchEvent(evt); } }; }
firing a click event on an anchor element will trigger onbeforeunload event, so client engine sends remove desktop au. Then the target resource becomes unavailable.
debug info
- this issue doesn't happen in 7.x
- a user reported chrome and safari on iPad2 (iOS 9.2.1) also has this issue. (But I cannot reproduce this with physical iPad)
- He said if he visits the link generated by the AU response e.g. http://localhost:8080/zk8support/zkau/view/z_t59/dwnmed-0/ck7/test.pdf, he gets a 410 HTTP error on both iOS and Android. (But I cannot reproduce this issue)
- Android phones don't have such issue in the example above.
workaround
<script defer="true"><![CDATA[ zAu.cmd0.download = function (url) { if (url) { var ifr = jq('#zk_download')[0]; if (ifr) { ifr.src = url; } else { var html = '<iframe src="' + url + '" id="zk_download" name="zk_download" style="display:none;width:0;height:0;border:0" frameborder="0"></iframe>'; jq(document.body).append(html); } } }; ]]> </script>