2010-06-20 16 views
16

estoy teniendo algunas dificultades con AjaxForm carga de archivos y el almacén de blob motor de aplicación. Sospecho que la dificultad se debe a que el gestor de carga blobstore (subclase de blobstore_handlers.BlobstoreUploadHandler) ordena una respuesta de redirección, en lugar de devolver cualquier contenido, pero no estoy seguro. Espero obtener un documento XML con el que trabajar, y parece que llega al navegador como se esperaba, pero no puedo entenderlo, detalles a continuación.AjaxForm y aplicación del motor Blobstore

Mi motor de aplicación manipulador de carga del almacén de blob es el siguiente -

class UploadHandler(blobstore_handlers.BlobstoreUploadHandler): 
    def post(self): 
    upload_files = self.get_uploads('file') # 'file' is file upload field in the form 
    blob_info = upload_files[0] 

    entity_key = self.request.get("entityKey") 

    // Update a datastore entity with the blobkey (not shown) 

    // redirect to the uri for the updated entity 
    self.redirect('%s.xml' % entity_key) 

La redirección final es un URI en mi aplicación que devuelve un documento XML. Al mirar la salida del servidor, no hay indicación de que algo esté mal: se atiende el redireccionamiento y devuelve el documento xml como se esperaba, con el tipo de mime correcto, para que el envío del formulario se vea bien y la respuesta del servidor a ese envío se vea bueno.

Mi cliente código del lado usando ajaxForm se ve de la siguiente manera (lo siento, es un poco obtuso, no creo que el problema es aquí, sin embargo) -

// Create the form 
var dialogForm = $("<form method='POST' enctype='multipart/form-data'>") 
    .append("<span>Upload File: </span><input type='file' name='file'/><br>") 
    .append("<input type='hidden' name='entityKey' value='" + entityKey + "'/>") 
    .append("<input type='hidden' name='entityField' value='image'/>") 
    .append("<input type='button' value='Wait...' disabled='disabled'/>");; 

dialogForm.ajaxForm(); 

// Turn the form button into a nice jQuery UI button and add a click handler 
$("input[type=button]", dialogForm[0]).button() 
    .click(function() { 
     log.info("Posting to : " + dialogForm.attr('action')); 
     dialogForm.ajaxSubmit({ 
     success: function(responseText, statusText, xhr, $form) { 
      log.info("Response: " + responseText + ", statusText: " + statusText + ", xhr: " + goog.debug.expose(xhr) + ", form:" + goog.debug.expose($form)); 
     } 
     }); 
    }); 

que establezca la 'acción' de la forma (y habilitar la botón) después -

$.get('/blob_upload_url', function(data) { 
    dialogForm.attr("action", data); 
    $("input[type=button]", dialogForm[0]).attr("value", "Upload").button("option", "disabled", false); 
}; 

estoy usando un poco de cierre de Google en allí también para el registro y la exposición de objetos. Todo se ve bien, como se esperaba, se está publicando correctamente en el servidor y se llama a la función de éxito. Si miro la estructura del documento en las herramientas de desarrollo de Chrome, puedo ver que el iFrame se crea brevemente para manejar la carga y respuesta del archivo.

El problema es que nunca consigo el documento XML en la respuesta. La salida del registro es el siguiente -

[ 18.642s] [Panel] Response: null, statusText: success, xhr: 0 = [object HTMLFormElement] 
length = 1 
selector = 
jquery = 1.4.2, form:0 = [object HTMLFormElement] 
length = 1 
selector = 
jquery = 1.4.2 
Resource interpreted as document but transferred with MIME type application/xml [ABCdefGH] 

La queja de cromo sobre el tipo MIME es probablemente muy relevante, pero no estoy haciendo la conexión :) - al menos eso significa que se está haciendo en el documento XML algún punto. En Chrome vista de los recursos, se puede ver el POST, y que la respuesta es una redirección 302, y luego la solicitud GET posterior - la cabecera de los cuales se ve bien -

vista
Request URL:http://localhost:8081/_ah/upload/ABCdefGH 
Request Method:GET 
Status Code:200 OK 
Request Headers 
Referer:http://localhost:8081/ 
User-Agent:Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_4; en-US) AppleWebKit/533.4 (KHTML, like Gecko) Chrome/5.0.375.70 Safari/533.4 
Response Headers 
Cache-Control:no-cache 
Content-Length:2325 
Content-Type:application/xml 
Date:Sun, 20 Jun 2010 20:47:39 GMT 
Expires:Fri, 01 Jan 1990 00:00:00 GMT 
Server:Development/1.0 

recursos Chrome no me la va a mostrar contenido de ese documento (solo en blanco) pero firefox lo hace y el documento xml se ve bien. Sin embargo, Firefox ofrece el mismo resultado final: nulo para el texto de respuesta ajaxSubmit().

Calculo Estoy teniendo un fundido cerebro aquí en alguna parte, pero en realidad me tiene confundido. Cualquier punteros para conseguir que el documento XML sería grande - vivas,

Colin

+0

Supongo que Ajaxform no maneja los redireccionamientos correctamente, ya sea solo o porque usa un componente flash que no los maneja. Intente cambiar su controlador de carga a un manejador de solicitudes normal y devolver el documento directamente en lugar de una redirección, y vea si eso marca alguna diferencia; eso al menos le indicará si se trata de la redirección o no. –

+0

Sí, está bien - confirmó que se redirigió como se sugiere (no usa flash). ¿Cómo es que el blobstore UploadHandler ordena una redirección? ¿Alguien tiene una carga de estilo ajax trabajando con la tienda de blob? es decir, ¿el usuario no experimenta la redirección o la actualización de una página? Gracias. – hawkett

+0

http://forum.jquery.com/topic/jquery-form-plugin-and-app-engine-blobstore#14737000001093602 - autor que confirma que no puede perseguir la redirección. ¿Parece que el comportamiento de redirección * forzado * es excesivo con la API del almacén de blob? – hawkett

Respuesta

0

Si usted es de 5 meses atrapados en el mismo problema .. Creo que usted debe preguntar aquí:

http://www.google.com/support/forum/p/Chrome/

+0

Es casi seguro que este problema no es un problema de Chrome: ocurre en los otros navegadores. El problema, dependiendo de cómo lo mires, es o bien la API de blobstore ordenando una redirección, o AjaxForm no persiguiendo esa redirección. A falta de justificación por parte de google, me inclino por la primera, parece que han creado un aro para saltar sin ningún motivo. – hawkett

4

Este es un método que he usado (solo probado en Chrome) ligeramente modificado. No es AjaxForm pero funciona.

function upload_files(entityKey, files, url, progress_callback) { 
    var xhr = new XMLHttpRequest(), formData = new FormData(); 
    xhr.upload['onprogress'] = progress_callback; 

    formData.append('entityKey', entityKey); 
    $.each(files, function(i, file) { formData.append('file[]', file);}); 

    xhr.open("post", url, true); 
    xhr.setRequestHeader("Cache-Control", "no-cache"); 
    xhr.send(formData); 
} 

El entityKey está disponible como un parámetro en el servidor. El parámetro 'archivos' proviene del atributo 'archivos' del elemento de formulario de entrada de tipo de archivo (como una matriz para admitir múltiples).El parámetro 'progress_callback' es una función que toma un objeto que tiene (al menos) un campo 'cargado' y 'total' (la unidad es bytes). No le importa la respuesta del servidor.

+0

Ok, entonces, en lugar de esperar la respuesta, use la devolución de llamada de progreso para identificar cuándo se completó la carga (¿cargado == total?) Y luego busque la entidad actualizada por separado, como usted dice, ignore por completo la respuesta del servidor. Ejército de reserva. – hawkett

1

así es como lo resolví. Agregué una identificación aleatoria generada en javascript enviar junto con el archivo. una vez completada la carga, configure mi servidor para recordar la asociación de ese ID aleatorio y el archivo cargado durante un tiempo. Envío otra consulta a una URL predefinida como mysite.com/blobdata/that_random_id_i_renerated para solicitar el archivo que acaba de subir. funcionó.

Cuestiones relacionadas