6

Próbuję przesłać niektóre dane binarne, w szczególności obiekt ByteArray reprezentujący obraz PNG, do serwera za pomocą klasy URLLoader w połączeniu z parametrem URLRequest.Nieoczekiwany wyjątek bezpieczeństwa Flash podczas korzystania z narzędzia URLLoader

Po ustawieniu wartości contentType obiektu URLRequest na "wieloczęściowe/dane formularzy" zamiast wartości domyślnej, wywołanie funkcji urlLoader.load() powoduje wyjątek zabezpieczeń.

Kiedy domyślnie zostawiam właściwość contentType, działa ona prawidłowo, ale zajmuje dużo czasu (proporcjonalnie do długości pliku PNG), aby przesłać plik na serwer.

Moje pytanie brzmi: DLACZEGO otrzymuję wyjątek bezpieczeństwa? I jak mogę tego uniknąć?

Należy zauważyć, że mój plik SWF jest serwowany z serwera programistycznego, a nie z lokalnego systemu plików (dokładniej mówiąc, serwer programistyczny Google App Engine).

Oto kod:

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

Odpowiedz

13

To może być możliwe, że contentType nie odnosi się do tego, co dane wysyłać, ale do tego, co dane pojawić. Spróbuj ustawić requestHeaders, że powinno działać:

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

Również znalazłem kawałek kodu, gdzie w jednym z moich projektów. Kod działa i wysyła niektóre binarne dane JPEG do serwera przy użyciu testu POST. Zrobiłem to jakiś czas temu i nie potrafię wyjaśnić, dlaczego robiłem to w ten sposób, ale może to pomaga. Ja wklejając go jako to:

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

Dziękuję bardzo! Ostatniej nocy byłam zaskoczona godzinami ... Musiałem poprawić trochę rzeczy, więc zobacz moją odpowiedź na dokładnie, jak to się skończyło. – Cameron

+0

Nie ma za co. Tak, dobrze wiedzieć o granicy. Pozdrowienia. – evilpenguin

+0

dziękuję bardzo za bardzo ... Rzadko robię flashowanie dev, ale potrzebowałem aktualizacji uploadera, co w końcu mnie uratowało :) – will

8

Tylko dla kompletności boską, tu jest jak skończyło się skonfigurowaniu URLRequest (cała reszta pozostała taka sama):

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

Klucz, jak wskazano przez evilpenguin, nie było ustawianie właściwości contentType w ogóle, ale umieszczenie jej w nagłówku. Używając tylko "wieloczęściowych/formularzy danych" dostałem jednak błąd po stronie serwera dotyczący niepoprawnych granic POST, więc skończyłem używając a class called UploadPostHelper, aby utworzyć prawidłową granicę i treść POST do przesyłania plików.

Naprawiono tajemniczy błąd bezpieczeństwa (nadal nie wiem, dlaczego tak się stało) i bardzo długie oczekiwanie na przesyłanie.

Należy zauważyć, że przykładowy kod do używania UploadPostHelper obejmuje ustawienie właściwości contentType obiektu URLRequest, a to najwyraźniej działa dla niektórych osób, ale nie w moim przypadku.

4

Miałem ten sam problem. Udało się to dobrze po przesłaniu do skryptu PHP, ale nie do skryptu ASP. Po przeniesieniu typu zawartości do requestHeader działa poprawnie. Oto mój kod:

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