Scenario: What I have is an upload form that reports on the upload progress using the nginx uploadProgress module. The code below works fine in Firefox, but with Chrome and Chromium the AJAX is not fired while the page is loading and will only be run when I stop the request (so half way through the upload). I'm lost as to why it doesn't work. So any help is much appreciated.
What I also find bizarre is that Chrome/Chromium seem to update the window status bar with the upload progress without me telling it to.
There's no where I can see where I'm setting that. Is it possible that Chrome has an internal progress meter?
upload.js
$(document).ready(function()
{
$('form').uploadProgress(
{
uploading: function(upload)
{
$('#percents').html(upload.percents+'%');
$('#progressbar').css({width: upload.percents+'%'});
},
progressUrl: "/progress",
interval: 3
});
})
jquery.uploadProgress.js
/*
* jquery.uploadProgress
*
* Copyright (c) 2008 Piotr Sarnacki (drogomir.com)
* - Original release.
*
* Copyright (c) 2011 Mathew Davies (thepixeldeveloper@googlemail.com)
* - Refactored a lot of code into their own functions
*
* Licensed under the MIT license:
* http://www.opensource.org/licenses/mit-license.php
*
*/
(function($)
{
/**
* Generate a UUID used to uniquely identify form uploads.
*
* @return string
*/
function generate_uuid()
{
var uuid = "";
for (i = 0; i < 32; i++)
{
uuid += Math.floor(Math.random() * 16).toString(16);
}
return uuid;
}
/**
* Calls the progress URL to get the latest statistics from
* the uploaded form.
*
* @return void
*/
function update(object, options)
{
$.ajax(
{
type: 'GET',
cache: false,
dataType: options.dataType,
url: options.progressUrl,
beforeSend: function(xhr)
{
xhr.setRequestHeader("X-Progress-ID", options.uuid);
},
success: function(upload)
{
alert('progress ...');
if (upload)
{
if (upload.state == 'uploading')
{
upload.percents = Math.floor((upload.received / upload.size) * 1024) / 10;
options.uploading(upload);
}
if (upload.state == 'done' || upload.state == 'error')
{
window.clearTimeout(options.timer);
}
if (upload.state == 'done')
{
upload.percents = 100;
options.done(upload);
}
if (upload.state == 'error')
{
upload.percents = 0;
options.error(upload);
}
}
}
});
}
/**
* Updates the form action to use the UUID.
*/
function update_form_action(form, uuid)
{
if(old_id = /X-Progress-ID=([^&]+)/.exec(form.attr("action")))
{
var action = form.attr("action").replace(old_id[1], uuid);
}
else
{
var action = form.attr("action") + "?X-Progress-ID=" + uuid;
}
form.attr("action", action);
}
$.fn.uploadProgress = function(options)
{
var options = $.extend(
{
dataType: "json",
interval: 2000,
progressUrl: "/progress",
start: function() {},
uploading: function() {},
done: function() {},
error: function() {},
timer: ""
}, options);
return this.each(function()
{
$(this).submit(function()
{
var $this = $(this);
// Generate a new UUID
options.uuid = generate_uuid();
// Update form action with ID
update_form_action($this, options.uuid);
// Start callback
options.start();
// Start process
options.timer = window.setInterval(function()
{
update($this, op开发者_运维问答tions)
},
options.interval * 1000);
});
});
};
})(jQuery);
Seems like there is a reported issue within Webkit where XmlHttpRequest does not work as expected during file uploads / form posts.
Chrome bug report w/ links to webkit here: http://code.google.com/p/chromium/issues/detail?id=45196
精彩评论