6

Quello che sto cercando di fare è caricare alcuni dati binari, in particolare un ByteArray che rappresenta un'immagine PNG, su un server che utilizza la classe URLLoader in combinazione con URLRequest.Eccezione di Flash Security inattesa quando si utilizza URLLoader

Quando si imposta la proprietà contentType di URLRequest su "multipart/form-data" anziché sul valore predefinito, la chiamata a urlLoader.load() genera un'eccezione di sicurezza.

Quando lascio la proprietà contentType come predefinita, funziona correttamente, ma richiede molto tempo (proporzionale alla lunghezza del file PNG) per caricare il file sul server.

Quindi, la mia domanda è PERCHÉ ottengo questa eccezione di sicurezza? E come posso evitarlo?

Si noti che il mio SWF viene fornito da un server di sviluppo, non dal file system locale (il server di sviluppo di Google App Engine per la precisione).

Ecco il codice:

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); 
}); 

risposta

13

Potrebbe essere possibile che contentType non si riferisce a ciò che i dati inviati, ma a quali dati si riceve. Tenta di impostare la requestHeaders, che dovrebbe funzionare:

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

Inoltre, ho trovato un pezzo di codice in cui in uno dei miei progetti. Il codice funziona e invia alcuni dati JPEG binari al server, usando POST. L'ho fatto un po 'di tempo fa e non so spiegare perché ho fatto le cose in questo modo, ma forse è d'aiuto. Sto incollandolo come è:

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

Grazie mille! La scorsa notte sono stato perplesso per ore ... Ho dovuto modificare alcune cose, quindi vedi la mia risposta esattamente come ha funzionato – Cameron

+0

Prego. Sì, buono a sapere del confine. Saluti. – evilpenguin

+0

grazie mille ... molto raramente flash dev, ma avevo bisogno di aggiornare un uploader, e questo mi ha finalmente salvato :) – will

8

Solo per completezza, ecco come ho finito per impostare il mio oggetto URLRequest (tutto il resto è rimasto lo stesso):

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 chiave, come sottolineato da evilpenguin, non doveva impostare la proprietà contentType ma inserirla nell'intestazione. Usando solo 'multipart/form-data', tuttavia, ho ricevuto un errore sul lato server sui limiti POST non validi, quindi ho finito con l'utilizzo di a class called UploadPostHelper per creare un limite valido e il corpo POST per i caricamenti di file.

Questo ha risolto il misterioso errore di sicurezza (ancora non so perché è successo) e le lunghissime attese per gli upload.

Si noti che il codice di esempio per l'utilizzo di UploadPostHelper prevede l'impostazione della proprietà contentType dell'oggetto URLRequest e questo a quanto pare funziona per alcune persone, ma non nel mio caso.

4

Ho avuto lo stesso problema. Ha funzionato bene quando si inviava a uno script PHP, ma non a uno script ASP. Dopo aver spostato il tipo di contenuto su requestHeader, funziona correttamente. Ecco il mio codice:

// 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);