6

我試圖完成的是將一些二進制數據,特別是表示PNG圖像的ByteArray上傳到服務器,使用URLLoader類和URLRequest。使用URLLoader時發生意外的Flash安全異常

當我將URLRequest的contentType屬性設置爲'multipart/form-data'而不是默認值時,對urlLoader.load()的調用會導致安全異常。

當我將contentType屬性作爲默認值時,它工作正常,但需要很長時間(與PNG文件的長度成比例)才能將文件上載到服務器。

所以,我的問題是爲什麼我得到這個安全例外?我該如何避免它?

請注意,我的SWF文件是從開發服務器提供的,而不是本地文件系統(準確的說是Google App Engine開發服務器)。

下面是代碼:

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

回答

13

這可能是可能的,contentType並不是指你所發送的數據,但您會收到什麼樣的數據。嘗試設置requestHeaders,應該工作:

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

而且,我發現了一段代碼在我的項目之一,。代碼工作並使用POST將一些二進制JPEG數據發送到服務器。我前一陣子就是這樣,我無法解釋爲什麼我這樣做了,但也許有幫助。我粘貼它是:

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

非常感謝!昨晚我被困了好幾個小時...... 我不得不調整一些東西,所以看看我的答案是如何結束了工作 – Cameron 2009-08-13 18:28:31

+0

不客氣。是的,很高興知道邊界。問候。 – evilpenguin 2009-08-14 06:25:44

+0

非常感謝你sooo ...我很少做閃存開發,但我需要更新上傳,這最終救了我:) – will 2011-10-28 05:45:59

8

只是爲了完整起見,這裏是我是如何結束的設置我的URLRequest對象(一切保持不變):

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

的關鍵,正如evilpenguin所指出的那樣,並不是要設置contentType屬性,而是將其放在標題中。然而,只使用'multipart/form-data',我在服務器端出現了關於無效POST邊界的錯誤,所以我最終使用a class called UploadPostHelper爲文件上傳創建了一個有效的邊界和POST主體。

這修復了神祕的安全錯誤(我仍然不知道爲什麼會發生這種情況),並且很長時間等待上傳。

應該指出的是,使用UploadPostHelper的示例代碼涉及設置URLRequest對象的contentType屬性,這顯然適用於某些人,但在我的情況下不起作用。

4

我有同樣的問題。提交給PHP腳本時它工作正常,但不提供給ASP腳本。將內容類型移動到requestHeader後,它可以正常工作。這裏是我的代碼:

// 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); 
相關問題