使用URLLoader时出现意外的Flash安全异常

Cam*_*ron 6 securityexception file-upload urlrequest urlloader actionscript-3

我想要完成的是使用URLLoader类和URLRequest将一些二进制数据,特别是表示PNG图像的ByteArray上传到服务器.

当我将contentTypeURLRequest 的属性设置为'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);
});
Run Code Online (Sandbox Code Playgroud)

evi*_*uin 13

它可能contentType不是指您发送的数据,而是指您收到的数据.尝试设置requestHeaders,应该工作:

urlRequest.requestHeaders.push(new URLRequestHeader('Content-type', 'multipart/form-data'));
Run Code Online (Sandbox Code Playgroud)

另外,我在我的一个项目中找到了一段代码.该代码使用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);
}
Run Code Online (Sandbox Code Playgroud)


Cam*_*ron 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()));
Run Code Online (Sandbox Code Playgroud)

正如evilpenguin所指出的那样,关键是不要设置contentType属性,而是将其放在标题中.但是,仅使用'multipart/form-data',我在服务器端收到有关无效POST边界的错误,因此我最终使用了一个名为UploadPostHelper的类来创建有效的边界和POST主体以进行文件上传.

这修复了神秘的安全错误(我仍然不知道为什么会发生这种情况),以及很长时间等待上传.

应该注意的是,使用UploadPostHelper的示例代码涉及设置contentTypeURLRequest对象的属性,这显然适用于某些人,但不适用于我的情况.