Hi Martin,

indeed, I didn't expect us to put so much effort into this :P

Yes, IMHO Blob would be the default: Why use anything else with a modern browser?

Note that currently the whole download has to fit into memory, we could optimize this even further with the new file stream api.

I'd rather not build in all bells and whistles until somebody runs into a problem. Many information I've found about this solution is from 2013, so many workarounds might no longer be needed.

>The simplest thing ... #getLocation() non-final and use it in #initiate().
>This way the developer can use any kind of detection for the best location
> WDYT

Exactly my thoughts.

Sven

On 23.03.2017 15:31, Martin Grigorov wrote:
This new AjaxDownload utility became much smarter than the original one! :-)

I see that you have changed the default location to be Blob.
According to http://caniuse.com/#search=blob it could be used with pretty
much all modern browsers!
Do we need to add support for fallbacks via ClientProperties and UserAgent
? Or we will keep it simple until someone really needs this ? The simplest
thing we can do is make #getLocation() non-final and use it in #initiate().
This way the developer can use any kind of detection for the best location
type.
WDYT ?


Martin Grigorov
Wicket Training and Consulting
https://twitter.com/mtgrigorov

On Thu, Mar 23, 2017 at 3:22 PM, <svenme...@apache.org> wrote:

WICKET-6286 added Location.Blob

downloads via Blob and createObjectURL

Project: http://git-wip-us.apache.org/repos/asf/wicket/repo
Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/10175f1e
Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/10175f1e
Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/10175f1e

Branch: refs/heads/master
Commit: 10175f1ef969ae0feccafc9bf997c78e42c8cc54
Parents: e7c2320
Author: Sven Meier <svenme...@apache.org>
Authored: Thu Mar 23 15:22:15 2017 +0100
Committer: Sven Meier <svenme...@apache.org>
Committed: Thu Mar 23 15:22:15 2017 +0100

----------------------------------------------------------------------
  .../examples/ajax/builtin/AjaxDownloadPage.html |  3 +-
  .../examples/ajax/builtin/AjaxDownloadPage.java | 48 ++++++++++++++++++-
  .../wicket/extensions/ajax/AjaxDownload.java    |  9 +++-
  .../extensions/ajax/wicket-ajaxdownload.js      | 49 ++++++++++++++++++--
  4 files changed, 101 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/wicket/blob/
10175f1e/wicket-examples/src/main/java/org/apache/wicket/
examples/ajax/builtin/AjaxDownloadPage.html
----------------------------------------------------------------------
diff --git a/wicket-examples/src/main/java/org/apache/wicket/
examples/ajax/builtin/AjaxDownloadPage.html b/wicket-examples/src/main/
java/org/apache/wicket/examples/ajax/builtin/AjaxDownloadPage.html
index 0be7fe2..dd7e3ab 100644
--- a/wicket-examples/src/main/java/org/apache/wicket/
examples/ajax/builtin/AjaxDownloadPage.html
+++ b/wicket-examples/src/main/java/org/apache/wicket/
examples/ajax/builtin/AjaxDownloadPage.html
@@ -27,7 +27,8 @@
  </p>

  <ul>
-       <li>via an <a wicket:id="download">iframe</a>.</li>
+       <li>for <a wicket:id="download">modern browsers</a>.</li>
+       <li>in an <a wicket:id="downloadIframe">iframe</a>.</li>
         <li>in a <a wicket:id="downloadInNewWindow">new browser
window</a>.</li>
         <li>in the <a wicket:id="downloadInSameWindow">same
window</a>.</li>
  </ul>

http://git-wip-us.apache.org/repos/asf/wicket/blob/
10175f1e/wicket-examples/src/main/java/org/apache/wicket/
examples/ajax/builtin/AjaxDownloadPage.java
----------------------------------------------------------------------
diff --git a/wicket-examples/src/main/java/org/apache/wicket/
examples/ajax/builtin/AjaxDownloadPage.java b/wicket-examples/src/main/
java/org/apache/wicket/examples/ajax/builtin/AjaxDownloadPage.java
index b589091..6d1aa3e 100644
--- a/wicket-examples/src/main/java/org/apache/wicket/
examples/ajax/builtin/AjaxDownloadPage.java
+++ b/wicket-examples/src/main/java/org/apache/wicket/
examples/ajax/builtin/AjaxDownloadPage.java
@@ -21,6 +21,7 @@ import java.util.concurrent.TimeUnit;
  import org.apache.wicket.ajax.AjaxRequestTarget;
  import org.apache.wicket.ajax.markup.html.AjaxLink;
  import org.apache.wicket.extensions.ajax.AjaxDownload;
+import org.apache.wicket.extensions.ajax.AjaxDownload.Location;
  import org.apache.wicket.markup.html.WebMarkupContainer;
  import org.apache.wicket.request.http.flow.AbortWithHttpErrorCodeExceptio
n;
  import org.apache.wicket.request.resource.ContentDisposition;
@@ -51,6 +52,8 @@ public class AjaxDownloadPage extends BasePage
                 add(downloadingContainer);

                 initDownload();
+
+               initDownloadInIframe();

                 initDownloadInNewWindow();

@@ -67,7 +70,7 @@ public class AjaxDownloadPage extends BasePage
                 // download cannot continue on page refresh
                 downloadingContainer.setVisible(false);
         }
-
+
         private void initDownload()
         {
                 IResource resource = new ExampleResource("downloaded via
ajax")
@@ -109,6 +112,49 @@ public class AjaxDownloadPage extends BasePage
                         }
                 });
         }
+
+       private void initDownloadInIframe()
+       {
+               IResource resource = new ExampleResource("downloaded via
ajax in iframe")
+                       .setContentDisposition(
ContentDisposition.ATTACHMENT);
+
+               final AjaxDownload download = new AjaxDownload(resource) {
+
+                       @Override
+                       protected void onBeforeDownload(AjaxRequestTarget
target)
+                       {
+                               downloadingContainer.setVisible(true);
+                               target.add(downloadingContainer);
+                       }
+
+                       @Override
+                       protected void onDownloadSuccess(AjaxRequestTarget
target)
+                       {
+                               downloadingContainer.setVisible(false);
+                               target.add(downloadingContainer);
+                       }
+
+                       @Override
+                       protected void onDownloadFailed(AjaxRequestTarget
target)
+                       {
+                               downloadingContainer.setVisible(false);
+                               target.add(downloadingContainer);
+
+                               target.appendJavaScript("alert('Download
failed');");
+                       }
+               };
+               download.setLocation(Location.IFrame);
+               add(download);
+
+               add(new AjaxLink<Void>("downloadIframe")
+               {
+                       @Override
+                       public void onClick(AjaxRequestTarget target)
+                       {
+                               download.initiate(target);
+                       }
+               });
+       }

         private void initDownloadReference()
         {

http://git-wip-us.apache.org/repos/asf/wicket/blob/
10175f1e/wicket-extensions/src/main/java/org/apache/
wicket/extensions/ajax/AjaxDownload.java
----------------------------------------------------------------------
diff --git a/wicket-extensions/src/main/java/org/apache/wicket/
extensions/ajax/AjaxDownload.java b/wicket-extensions/src/main/
java/org/apache/wicket/extensions/ajax/AjaxDownload.java
index 804a794..e50cf9d 100644
--- a/wicket-extensions/src/main/java/org/apache/wicket/
extensions/ajax/AjaxDownload.java
+++ b/wicket-extensions/src/main/java/org/apache/wicket/
extensions/ajax/AjaxDownload.java
@@ -73,6 +73,13 @@ public class AjaxDownload extends
AbstractDefaultAjaxBehavior

         public enum Location {
                 /**
+                * The resource will be downloaded into a blob.
+                * <p>
+                * This is recommended for modern browsers.
+                */
+               Blob,
+
+               /**
                  * The resource will be downloaded via a temporary created
iframe, the resource has to be a
                  * {@link ContentDisposition#ATTACHMENT}.
                  * <p>
@@ -115,7 +122,7 @@ public class AjaxDownload extends
AbstractDefaultAjaxBehavior

         private PageParameters resourceParameters;

-       private Location location = Location.IFrame;
+       private Location location = Location.Blob;

         /**
          * Download of a {@link Resource}.

http://git-wip-us.apache.org/repos/asf/wicket/blob/
10175f1e/wicket-extensions/src/main/java/org/apache/
wicket/extensions/ajax/wicket-ajaxdownload.js
----------------------------------------------------------------------
diff --git a/wicket-extensions/src/main/java/org/apache/wicket/
extensions/ajax/wicket-ajaxdownload.js b/wicket-extensions/src/main/
java/org/apache/wicket/extensions/ajax/wicket-ajaxdownload.js
index ec81ca4..7c320c3 100644
--- a/wicket-extensions/src/main/java/org/apache/wicket/
extensions/ajax/wicket-ajaxdownload.js
+++ b/wicket-extensions/src/main/java/org/apache/wicket/
extensions/ajax/wicket-ajaxdownload.js
@@ -29,10 +29,10 @@
                 initiate : function(settings) {

                         var notifyServer = function(result) {
-                settings.attributes.ep = settings.attributes.ep || {};
-                settings.attributes.ep.result = result;
-                Wicket.Ajax.ajax(settings.attributes);
-            };
+                               settings.attributes.ep =
settings.attributes.ep || {};
+                               settings.attributes.ep.result = result;
+                               Wicket.Ajax.ajax(settings.attributes);
+                       };

                         var checkComplete = function(watcher) {
                                 var result;
@@ -82,7 +82,7 @@
                                                 }
                                         }
                                 });
-                       } else {
+                       } else if (settings.method == 'iframe') {
                                 var frame = 
jQuery("<iframe></iframe>").hide().prop("src",
settings.downloadUrl).appendTo("body");
                                 checkComplete({
                                         html: function() {
@@ -96,6 +96,45 @@
                                                 }, 0);
                                         }
                                 });
+                       } else {
+                               jQuery.ajax({
+                                       type: 'get',
+                                       url: settings.downloadUrl,
+                                       success: function (response,
status, xhr) {
+                                               var filename = "";
+                                               var disposition =
xhr.getResponseHeader("Content-Disposition");
+                                               if (disposition &&
disposition.indexOf("attachment") !== -1) {
+                                                       var matches =
/filename[^;=\n]*=(([""]).*?\2|[^;\n]*)/.exec(disposition);
+                                                       if (matches !=
null && matches[1]) {
+                                                               filename =
matches[1].replace(/[""]/g, "");
+                                                       }
+                                               }
+
+                                               var type =
xhr.getResponseHeader("Content-Type");
+                                               var blob = new
Blob([response], {type: type});
+
+                                               var blobUrl = (window.URL
|| window.webkitURL).createObjectURL(blob);
+
+                                               var anchor =
jQuery("<a></a>")
+                                                       .prop("href",
blobUrl)
+                                                       .prop("download",
filename)
+                                                       .appendTo("body")
+                                                       .hide();
+
+                                               anchor[0].click();
+
+                                               setTimeout(function () {
+
  URL.revokeObjectURL(blobUrl);
+                                                       anchor.remove();
+                                               }, 100);
+
+                                               notifyServer("success");
+                                       },
+
+                                       error: function (response, status,
xhr) {
+                                               notifyServer("failed");
+                                       }
+                               });
                         }
                 }
         };



Reply via email to