2012-09-27 35 views
6

Estoy intentando subir un archivo grande (1.5GB) a Amazon S3 utilizando el corte de archivos REST Api y HTML5. Así es como el código de carga se ve como (código simplificada para facilitar la lectura):Amazon S3 CORS PUT falla

File.prototype.slice = File.prototype.webkitSlice || File.prototype.mozSlice || File.prototype.slice; 

var length = u.settings.chunk_size; // 6MB 
var start = chunk * length; 
var end = Math.min(start + length, u.file.size); 

var xhr = new XMLHttpRequest(); 
var path = "/" + u.settings.key; 

path += "?partNumber=" + chunk + "&uploadId=" + u.upload_id; 

var method = "PUT"; 
var authorization = "AWS " + u.settings.access_key + ":" + signature; 
var blob = u.file.slice(start, end); 

xhr.upload.addEventListener("progress", progress_handler, true); 
xhr.addEventListener("readystatechange", handler, true); 
xhr.addEventListener("error", error_handler, true); 
xhr.addEventListener("timeout", error_handler, true); 

xhr.open(method, u.settings.host + path, true); 

xhr.setRequestHeader("x-amz-date", date); 
xhr.setRequestHeader("Authorization", authorization); 
xhr.setRequestHeader("Content-Type", u.settings.content_type); 
xhr.setRequestHeader("Content-Disposition", "attachment; filename=" + u.file.name); 

xhr.send(blob); 

chunk_size es 6MB. Después de que un fragmento termina de cargarse, el siguiente sigue, y así sucesivamente. Pero a veces (cada 80 trozos más o menos), la solicitud PUT falla, con e.type == "error", e.target.status == 0 (lo que me sorprende) y e.target.responseText == "". Después de que falla un trozo, el código vuelve a intentar cargarlo y obtiene exactamente el mismo error. Cuando actualizo la página y continúo la carga (¡el mismo fragmento!), Funciona como un amuleto (por 80 pedazos más o menos, cuando se pega de nuevo). Así es como se ve en la solicitud de herramientas de Chrome dev:

enter image description here enter image description here enter image description here

Cualquier idea por qué esto podría suceder, o cómo depurar algo como esto?

EDIT: Aquí está la respuesta OPTIONS:

enter image description here

Respuesta

4

Finalmente encontré el problema sniffing de paquetes: hay dos cuestiones:

  1. para PUT peticiones que llegan un 4xx (no probaron para otros 2xx respuestas no), la solicitud xhr regresa como abortado (estado = 0); Todavía no han encontrado una explicación para eso, echa un vistazo a Why does a PUT 403 show up as Aborted?

  2. Amazon S3 respondió con una 403 que dijo RequestTimeTooSkewed, porque mis firmas se generan cuando la carga se inicia, y después de 15 minutos (el tiempo de espera que desencadena el error RequestTimeTooSkewed), falla y las firmas deben regenerarse. Ese error 403 nunca se ve en la consola de herramientas dev o por el código JS, debido al primer problema ..

Después de la regeneración de las firmas, todo funciona a las mil maravillas.

+0

Sí, lo ideal sería que firme la solicitud al igual que los está enviando en lugar de todo a la vez al principio. –

+0

@RyanParman Sí, es correcto, pero mi biblioteca está en JS y necesito generar firmas del lado del servidor, y preferiría hacer menos solicitudes al servidor. –

+0

Ah, tengo. Sí, eso hace la diferencia. :) –

2

¿Verificó si el navegador está haciendo ninguna petición 'opciones'. En caso afirmativo, ¿cuáles son los encabezados de respuesta?

+0

echa un vistazo a mi edición –