Skip to content

Commit

Permalink
Add support for JSON-P cross domain updates, like in the case where t…
Browse files Browse the repository at this point in the history
…he upload server is not the same as the web server

Signed-off-by: Piotr Sarnacki <drogus@gmail.com>
  • Loading branch information
deadprogram authored and drogus committed Feb 10, 2009
1 parent 54a24b6 commit a518b05
Show file tree
Hide file tree
Showing 2 changed files with 129 additions and 113 deletions.
23 changes: 21 additions & 2 deletions README
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -37,17 +37,35 @@ $(function() {
/* scripts locations for safari */ /* scripts locations for safari */
jqueryPath: "../lib/jquery.js", jqueryPath: "../lib/jquery.js",
uploadProgressPath: "../jquery.uploadProgress.js", uploadProgressPath: "../jquery.uploadProgress.js",
/* function called each time bar is updated */ /* function called each time bar is updated */
uploading: function(upload) {$('#percents').html(upload.percents+'%');}, uploading: function(upload) {$('#percents').html(upload.percents+'%');},
/* selector or element that will be updated */ /* selector or element that will be updated */
progressBar: "#progressbar", progressBar: "#progressbar",
/* progress reports url */ /* progress reports url */
progressUrl: "/progress", progressUrl: "/progress",
/* how often will bar be updated */ /* how often will bar be updated */
interval: 2000 interval: 2000
}); });
}); });


If you need to update the progress bar from a different domain or subdomain, liek if your upload server is different from your normal web server, you can try the JSON-P protocol, like this:
$(function() {
$('form').uploadProgress({
/* scripts locations for safari */
jqueryPath: "../lib/jquery.js",
uploadProgressPath: "../jquery.uploadProgress.js",
/* function called each time bar is updated */
uploading: function(upload) {$('#percents').html(upload.percents+'%');},
/* selector or element that will be updated */
progressBar: "#progressbar",
/* progress reports url in a different domain or subdomain from caller */
progressUrl: "uploads.somewhere.com/progress",
/* how often will bar be updated */
interval: 2000,
/* use json-p for cross-domain call */
dataType: 'jsonp'
});
});


defaults: defaults:


Expand All @@ -61,3 +79,4 @@ success: function() {}
error: function() {} error: function() {}
uploadProgressPath: '/javascripts/jquery.js' uploadProgressPath: '/javascripts/jquery.js'
jqueryPath: '/javascripts/jquery.uploadProgress.js' jqueryPath: '/javascripts/jquery.uploadProgress.js'
dataType: 'json'
219 changes: 108 additions & 111 deletions jquery.uploadProgress.js
Original file line number Original file line Diff line number Diff line change
@@ -1,119 +1,116 @@
/* /*
* jquery.uploadProgress * jquery.uploadProgress
* *
* Copyright (c) 2008 Piotr Sarnacki (drogomir.com) * Copyright (c) 2008 Piotr Sarnacki (drogomir.com)
* *
* Licensed under the MIT license: * Licensed under the MIT license:
* http://www.opensource.org/licenses/mit-license.php * http://www.opensource.org/licenses/mit-license.php
* *
*/ */
(function($) { (function($) {
$.fn.uploadProgress = function(options) { $.fn.uploadProgress = function(options) {
options = $.extend({ options = $.extend({
interval: 2000, dataType: "json",
progressBar: "#progressbar", interval: 2000,
progressUrl: "/progress", progressBar: "#progressbar",
start: function() {}, progressUrl: "/progress",
uploading: function() {}, start: function() {},
complete: function() {}, uploading: function() {},
success: function() {}, complete: function() {},
error: function() {}, success: function() {},
preloadImages: [], error: function() {},
uploadProgressPath: '/javascripts/jquery.uploadProgress.js', preloadImages: [],
jqueryPath: '/javascripts/jquery.js', uploadProgressPath: '/javascripts/jquery.uploadProgress.js',
timer: "" jqueryPath: '/javascripts/jquery.js',
}, options); timer: ""

}, options);
$(function() {
//preload images
for(var i = 0; i<options.preloadImages.length; i++)
{
options.preloadImages[i] = $("<img>").attr("src", options.preloadImages[i]);
}
/* tried to add iframe after submit (to not always load it) but it won't work.
safari can't get scripts properly while submitting files */
if($.browser.safari && top.document == document) {
/* iframe to send ajax requests in safari
thanks to Michele Finotto for idea */
iframe = document.createElement('iframe');
iframe.name = "progressFrame";
$(iframe).css({width: '0', height: '0', position: 'absolute', top: '-3000px'});
document.body.appendChild(iframe);

var d = iframe.contentWindow.document;
d.open();
/* weird - safari won't load scripts without this lines... */
d.write('<html><head></head><body></body></html>');
d.close();

var b = d.body;
var s = d.createElement('script');
s.src = options.jqueryPath;
/* must be sure that jquery is loaded */
s.onload = function() {
var s1 = d.createElement('script');
s1.src = options.uploadProgressPath;
b.appendChild(s1);
}
b.appendChild(s);
}
});


return this.each(function(){ $(function() {
$(this).bind('submit', function() { //preload images
var uuid = ""; for(var i = 0; i<options.preloadImages.length; i++)
for (i = 0; i < 32; i++) { uuid += Math.floor(Math.random() * 16).toString(16); } {

options.preloadImages[i] = $("<img>").attr("src", options.preloadImages[i]);
/* update uuid */ }
options.uuid = uuid; /* tried to add iframe after submit (to not always load it) but it won't work.
/* start callback */ safari can't get scripts properly while submitting files */
options.start(); if($.browser.safari && top.document == document) {

/* iframe to send ajax requests in safari
/* patch the form-action tag to include the progress-id thanks to Michele Finotto for idea */
if X-Progress-ID has been already added just replace it */ iframe = document.createElement('iframe');
if(old_id = /X-Progress-ID=([^&]+)/.exec($(this).attr("action"))) { iframe.name = "progressFrame";
var action = $(this).attr("action").replace(old_id[1], uuid); $(iframe).css({width: '0', height: '0', position: 'absolute', top: '-3000px'});
$(this).attr("action", action); document.body.appendChild(iframe);
} else {
$(this).attr("action", jQuery(this).attr("action") + "?X-Progress-ID=" + uuid); var d = iframe.contentWindow.document;
} d.open();
var uploadProgress = $.browser.safari ? progressFrame.jQuery.uploadProgress : jQuery.uploadProgress; /* weird - safari won't load scripts without this lines... */
options.timer = window.setInterval(function() { uploadProgress(this, options) }, options.interval); d.write('<html><head></head><body></body></html>');
}); d.close();
});
var b = d.body;
var s = d.createElement('script');
s.src = options.jqueryPath;
/* must be sure that jquery is loaded */
s.onload = function() {
var s1 = d.createElement('script');
s1.src = options.uploadProgressPath;
b.appendChild(s1);
}
b.appendChild(s);
}
});

return this.each(function(){
$(this).bind('submit', function() {
var uuid = "";
for (i = 0; i < 32; i++) { uuid += Math.floor(Math.random() * 16).toString(16); }

/* update uuid */
options.uuid = uuid;
/* start callback */
options.start();

/* patch the form-action tag to include the progress-id if X-Progress-ID has been already added just replace it */
if(old_id = /X-Progress-ID=([^&]+)/.exec($(this).attr("action"))) {
var action = $(this).attr("action").replace(old_id[1], uuid);
$(this).attr("action", action);
} else {
$(this).attr("action", jQuery(this).attr("action") + "?X-Progress-ID=" + uuid);
}
var uploadProgress = $.browser.safari ? progressFrame.jQuery.uploadProgress : jQuery.uploadProgress;
options.timer = window.setInterval(function() { uploadProgress(this, options) }, options.interval);
});
});
}; };

jQuery.uploadProgress = function(e, options) { jQuery.uploadProgress = function(e, options) {
jQuery.ajax({ jQuery.ajax({
type: "GET", type: "GET",
url: options.progressUrl, url: options.progressUrl + "?X-Progress-ID=" + options.uuid,
dataType: "json", dataType: options.dataType,
beforeSend: function(xhr) { success: function(upload) {
xhr.setRequestHeader("X-Progress-ID", options.uuid); if (upload.state == 'uploading') {
}, upload.percents = Math.floor((upload.received / upload.size)*1000)/10;
success: function(upload) {
if (upload.state == 'uploading') { var bar = $.browser.safari ? $(options.progressBar, parent.document) : $(options.progressBar);
upload.percents = Math.floor((upload.received / upload.size)*1000)/10; bar.css({width: upload.percents+'%'});

options.uploading(upload);
var bar = $.browser.safari ? $(options.progressBar, parent.document) : $(options.progressBar); }
bar.css({width: upload.percents+'%'});
options.uploading(upload); if (upload.state == 'done' || upload.state == 'error') {
} window.clearTimeout(options.timer);

options.complete(upload);
if (upload.state == 'done' || upload.state == 'error') { }
window.clearTimeout(options.timer);
options.complete(upload); if (upload.state == 'done') {
} options.success(upload);

}
if (upload.state == 'done') {
options.success(upload); if (upload.state == 'error') {
} options.error(upload);

}
if (upload.state == 'error') { }
options.error(upload); });
}
}
});
}; };

})(jQuery); })(jQuery);

0 comments on commit a518b05

Please sign in to comment.