views:

839

answers:

4

Hi, I am doing a site which submits a form to a different server. For upload progress tracking I use: for server side the NginxHttpUploadProgressModule und for client side - jquery-upload-progress. I have tested the setup by submitting the form to the same server and everything worked fine. Submitting to another server doesn't show the progress tracking(cross domain scripting). After hours of investigating this matter I came to the conclusion that the GET request generated by JQuery is at fault.

The query looks like this:

http://domain.com/upload/progress/?X-Progress-ID=39b2825934dbb2f33fe936df734ff840&callback=jsonp1249230337707&_=1249230345572

From the NginxHttpUploadProgressModule site:

The HTTP request to this location must have either an X-Progress-ID parameter or X-Progress-ID HTTP header containing the unique identifier as specified in your upload/POST request to the relevant tracked zone. If you are using the X-Progress-ID as a query-string parameter, ensure it is the LAST argument in the URL.

So, my question is how do I append the X-Progress-ID parameter to the end of the jquery GET request or set the X-Progress-ID header?

This doesn't work with jsonp(code from jquery.uploadProgress.js):

beforeSend: function(xhr) {
   xhr.setRequestHeader("X-Progress-ID", options.uuid);
}

Currently the request is generated this way(code from jquery.uploadProgress.js):

jQuery.uploadProgress = function(e, options) {
 jQuery.ajax({
 type: "GET",
 url: options.progressUrl + "?X-Progress-ID=" + options.uuid,
 dataType: options.dataType,
 success: function(upload) {
 ...
A: 

You simply cannot fire an XmlHttpRequest from a webpage, to a domain different from the page's domain. It violates security definitions that are default on all browsers. the only thing that I can think of that you can do is to use Flash or Silverlight to initiate the progress calls (Flash and Silverlight can, given the correct crossdomain.xml setup, send async requests from the browser to preset list of domains) or, setup a browser addin (say Firefox plugin, or IE ActiveX, or Embedded WinForm control) that can initiate calls without the same-domain restriction (as the request will not originate from the webpage, but from the browser itself)

Ken Egozi
That's not a problem with jsonp. My question was how to append the X-Progress-ID parameter to the Get request.
A: 

You need to install the Apache module for upload status as well, just using the jQuery plugin will not work.

To respond to Ken, I suggest you familiarize yourself with JSONP spec, since JSONP was created specifically to handle cross-domain Javascript calls.

Anyhow, this code works great in Passenger/Apache WITH my modified Apache module. Without modifying the extension for Nginx it will not work with a JSONP call.

Ron Evans
+2  A: 

I solved the GET parameter problem(code from jquery.uploadProgress.js):

jQuery.uploadProgress = function(e, options) {
  jQuery.ajax({
  type: "GET",
  url: options.progressUrl,
  dataType: options.dataType,
  data: "X-Progress-ID=" + options.uuid,
  success: function(upload) {
  ...

Modified GET request looks like this:

http://domain.com/upload/progress/?callback=jsonp1249230337707&_=1249230345572&X-Progress-ID=39b2825934dbb2f33fe936df734ff840

The nginx webserver is now correctly responding.

However as Ron Evans pointed out the client side progress tracking part won't work unless NginxHttpUploadProgressModule is modified.

A: 

I made a minor modification that solved the problem for me, you can check it out here:

http://github.com/tizoc/nginx-upload-progress-module/commit/a40b89f63b5a767faec3c78d826443a94dc5b126