6

Lo que intento lograr es cargar algunos datos binarios, específicamente un ByteArray que representa una imagen PNG, a un servidor que usa la clase URLLoader junto con URLRequest.Excepción inesperada de seguridad de Flash al utilizar URLLoader

Cuando establezco la propiedad contentType de URLRequest en 'multipart/form-data' en lugar de la predeterminada, la llamada a urlLoader.load() da como resultado una excepción de seguridad.

Cuando dejo la propiedad contentType como predeterminada, funciona bien, pero lleva mucho tiempo (proporcional a la longitud del archivo PNG) cargar el archivo en el servidor.

Entonces, mi pregunta es ¿POR QUÉ obtengo esta excepción de seguridad? ¿Y cómo puedo evitarlo?

Tenga en cuenta que mi SWF se sirve desde un servidor de desarrollo, no el sistema de archivos local (el servidor de desarrollo de Google App Engine, para ser precisos).

Aquí está el código:

var pngFile:ByteArray = PNGEncoder.encode(bitmapData); 

var urlRequest:URLRequest = new URLRequest('/API/uploadImage'); 

// With this line of code, the call to urlLoader.load() throws the following security exception: 
// 'SecurityError: Error #2176: Certain actions, such as those that display a pop-up window, may only be invoked upon user interaction, for example by a mouse click or button press.' 
urlRequest.contentType = 'multipart/form-data'; 

urlRequest.method = URLRequestMethod.POST; 
urlRequest.data = pngFile; 
urlRequest.requestHeaders.push(new URLRequestHeader('Cache-Control', 'no-cache')); 

urlLoader = new URLLoader(); 
urlLoader.dataFormat = URLLoaderDataFormat.TEXT; 
urlLoader.addEventListener(Event.COMPLETE, onUploadComplete); 
urlLoader.addEventListener(IOErrorEvent.IO_ERROR, onUploadError); 

NextFrame.addCallback(function() { 
    urlLoader.load(urlRequest); 
}); 

Respuesta

13

Podría ser posible que contentType no se refiere a los datos que envía, sino a lo que los datos que recibe. Tratar de establecer el requestHeaders, que debería funcionar:

urlRequest.requestHeaders.push(new URLRequestHeader('Content-type', 'multipart/form-data')); 

Además, he encontrado un pedazo de código en la que en uno de mis proyectos. El código funciona y envía algunos datos JPEG binarios al servidor, utilizando POST. Lo dicté hace algún tiempo y no puedo explicar por qué hice las cosas de esta manera, pero tal vez ayuda. Estoy pegando como es:

function sendData(submitPath:String, descriere:String):void { 
    // building the url request for uploading the jpeg to the server 
    var header:URLRequestHeader = new URLRequestHeader('Content-type', 'application/octet-stream'); 
    var jpgURLRequest:URLRequest = new URLRequest(submitPath+'/id/'+player.id+'/path/'+player.contentPath.replace('/','')+'/width/'+player.videoWidth+'/height/'+player.videoHeight+'/descriere/'+descriere+'/timp/'+time); 
    jpgURLRequest.requestHeaders.push(header); 
    jpgURLRequest.method = URLRequestMethod.POST; 
    jpgURLRequest.data = screenShot; 

    // sending the data to the server 
    var sender:URLLoader = new URLLoader(); 
    sender.load(jpgURLRequest); 
} 
+1

¡Muchas gracias! Estuve perdida durante horas anoche ... Tuve que modificar algunas cosas, así que vea mi respuesta para saber exactamente cómo terminó trabajando – Cameron

+0

De nada. Sí, es bueno saber sobre el límite. Saludos. – evilpenguin

+0

muchas gracias ... raramente hago revem flash, pero necesitaba actualizar un cargador, y esto finalmente me salvó :) – will

8

sólo por el bien integridad, aquí es cómo terminé la creación de mi objeto URLRequest (todo lo demás se mantuvo igual):

urlRequest.method = URLRequestMethod.POST; 
urlRequest.data = UploadPostHelper.getPostData('filename', pngFile); 
urlRequest.requestHeaders.push(new URLRequestHeader('Cache-Control', 'no-cache')); 
urlRequest.requestHeaders.push(new URLRequestHeader('Content-Type', 'multipart/form-data; boundary=' + UploadPostHelper.getBoundary())); 

La clave, como lo señaló evilpenguin, no era establecer la propiedad contentType sino colocarla en el encabezado. Sin embargo, con solo 'multipart/form-data', recibí un error en el lado del servidor sobre los límites de POST inválidos, así que terminé usando a class called UploadPostHelper para crear un límite válido y un cuerpo POST para las cargas de archivos.

Esto corrigió el misterioso error de seguridad (aún no sé por qué sucedió eso) y las largas esperas de carga.

Cabe señalar que el código de ejemplo para utilizar UploadPostHelper implica la configuración de la propiedad contentType del objeto URLRequest, y esto aparentemente funciona para algunas personas, pero no en mi caso.

4

Tuve el mismo problema. Funcionó bien al enviar a un script PHP, pero no a un script ASP. Después de mover el tipo de contenido a requestHeader, funciona correctamente. Aquí está mi código:

// Object containing form fields 
var formdata = new Object(); 
formdata.Email = textArray[8].text; 

//URLRequest containing the form fields and the attached image 
var urlRequest : URLRequest = new URLRequest(url); 
urlRequest.method = URLRequestMethod.POST; 
urlRequest.data = UploadPostHelper.getPostData(imageName, imageByteArray, formdata); 
urlRequest.requestHeaders.push(new URLRequestHeader('Cache-Control', 'no-cache')); 
urlRequest.requestHeaders.push(new URLRequestHeader('Content-Type', 'multipart/form-data; boundary=' + UploadPostHelper.getBoundary())); 

//URLLoader to load the request 
var urlLoader : URLLoader = new URLLoader(); 
urlLoader.dataFormat = URLLoaderDataFormat.BINARY; 
urlLoader.load(urlRequest); 
Cuestiones relacionadas