我想要完成的是使用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);
});
答案 0 :(得分: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 :(得分: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
属性,这显然适用于某些人,但不适用于我的情况。
答案 2 :(得分: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 );