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

发布于 2024-07-30 20:36:20 字数 1350 浏览 12 评论 0原文

我想要完成的任务是使用 URLLoader 类结合 URLRequest 将一些二进制数据(特别是表示 PNG 图像的 ByteArray)上传到服务器。

当我将 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);
});

What I am trying to accomplish is to upload some binary data, specifically a ByteArray representing a PNG image, to a server using the URLLoader class in conjunction with URLRequest.

When I set the contentType property of the URLRequest to 'multipart/form-data' instead of the default, the call to urlLoader.load() results in a security exception.

When I leave the contentType property as the default, it works fine, but takes a long time (proportional to the length of the PNG file) to upload the file to the server.

So, my question is WHY am I getting this security exception? And how can I avoid it?

Note that my SWF is being served up from a development server, not the local filesystem (the Google App Engine development server to be precise).

Here is the code:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

绝不服输 2024-08-06 20:36:27

我遇到过同样的问题。 提交到 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 );

I had the same issue. It worked fine when submitting to a PHP script, but not to an ASP script. After moving the content type to a requestHeader, it works correctly. Here's my code:

// 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 );
终陌 2024-08-06 20:36:25

为了完整起见,以下是我最终设置 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()));

正如vilpenguin 所指出的,关键是根本不设置 contentType 属性,而是将其放在标头中。 然而,仅使用“multipart/form-data”,我在服务器端收到有关无效 POST 边界的错误,因此我最终使用 一个名为UploadPostHelper 为文件上传创建有效的边界和 POST 正文。

这修复了神秘的安全错误(我仍然不知道为什么会发生),以及漫长的上传等待。

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

Just for completeness' sake, here is how I ended up setting up my URLRequest object (everything else stayed the same):

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

The key, as pointed out by evilpenguin, was not to set the contentType property at all but to put it in the header. Using just 'multipart/form-data' however, I got an error on the server side about invalid POST boundaries, so I ended up using a class called UploadPostHelper to create a valid boundary and POST body for file uploads.

This fixed the mysterious security error (I still don't know why that happened), and the very long waits for uploads.

It should be noted that the example code for using UploadPostHelper involves setting the contentType property of the URLRequest object, and this apparently works for some people, but not in my case.

歌入人心 2024-08-06 20:36:25

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

It could be possible that contentType does not refer to what data you send, but to what data you receive. Try to set the requestHeaders, that should work:

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

Also, I've found a piece of code where in one of my projects. The code works and sends some binary JPEG data to the server, using POST. I dit it some time ago and I can't explain why I did the things this way, but maybe it helps. I'm pasting it as is:

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);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文