【发布时间】:2015-04-26 23:53:20
【问题描述】:
我正在尝试使用 ActionScript 的 File.upload 在 Air SDK for iOS 环境中上传文件,但 File.upload 无法正常工作。调用 File.upload 后不执行文件上传的处理程序,也没有捕获到异常。当我检查服务器端的网络流量时,我发现执行 File.upload 后甚至没有 http 请求到达服务器。代码如下。
<?xml version="1.0" encoding="utf-8"?>
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark" title="HomeView">
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<fx:Script>
<![CDATA[
private var file:File;
private var dir:File;
//This method is executed to create a file and upload it when the Upload Button is pressed.
protected function OnUploadButtonPressed(event:MouseEvent):void{
trace("upload button clicked");
var urlReq:URLRequest = new URLRequest("http://10.60.99.31/MyPath/fileUploadTest.do");
urlReq.method = URLRequestMethod.POST;
var str:String = 'This is test';
var imageBytes:ByteArray = new ByteArray();
for ( var i:int = 0; i < str.length; i++ ) {
imageBytes.writeByte( str.charCodeAt(i) );
}
trace("size = " + imageBytes.length);
try{
dir = File.applicationStorageDirectory
//I also tested in several different directories
//dir = File.createTempDirectory();
//dir = File.documentsDirectory;
var now:Date = new Date();
var filename:String = "IMG" + now.fullYear + now.month + now.day + now.hours + now.minutes + now.seconds + now.milliseconds + ".txt";
file = dir.resolvePath( filename );
var stream:FileStream = new FileStream();
stream.open( file, FileMode.WRITE );
stream.writeBytes( imageBytes );
stream.close();
//Read back the file contents to check whether the file is written successfully.
var readStream:FileStream = new FileStream();
readStream.open(file, FileMode.READ);
var result:String = readStream.readUTFBytes(readStream.bytesAvailable);
trace("read back result = " + result);//The result is shown here as expected.
file.addEventListener( Event.COMPLETE, uploadComplete );
file.addEventListener( IOErrorEvent.IO_ERROR, ioError );
file.addEventListener( SecurityErrorEvent.SECURITY_ERROR, securityError );
file.addEventListener(ErrorEvent.ERROR, someError);
file.addEventListener(ProgressEvent.PROGRESS, onProgress);
file.upload( urlReq );//This line does not work. No handler is executed. No http request hit the server side.
trace("after file upload test");
}
catch( e:Error )
{
trace( e );
}
}
//Complete Handler
private function uploadComplete( event:Event ):void
{
trace( "Upload successful." );
}
//IOError handler
private function ioError( error:IOErrorEvent ):void
{
trace( "Upload failed: " + error.text );
}
//SecurityError handler
private function securityError(error:SecurityErrorEvent):void{
trace( "Security error:" + error.text );
}
//Other handler
private function someError(error:ErrorEvent):void{
trace("some error" + error.text);
}
//Progress handler
private function onProgress(event:ProgressEvent):void{
trace("progressHandler");
}
//This method is executed to invoke the URLLoader.load when the Tricky Button is pressed.
protected function OnTrickyButtonPressed(event:MouseEvent):void{
var urlReq:URLRequest = new URLRequest("http://200.60.99.31/");//This points to a non-existed server
urlReq.method = URLRequestMethod.POST;
urlReq.data = new ByteArray();
var loader:URLLoader = new URLLoader();
try{
loader.load(urlReq);//This line seems very important in iOS7. It decides whether the latter file.upload can work.
//But in iOS8, file.upload does not work even if this line is executed.
trace("after urlloader load");
}catch(e:Error){
trace(e);
}
}
]]>
</fx:Script>
<s:Button x="200" y="200" width="400" height="200" label="Upload" click="OnUploadButtonPressed(event)" />
<s:Button x="200" y="500" width="400" height="200" label="Tricky" click="OnTrickyButtonPressed(event)" />
</s:View>
在Air Simulator上执行后,运行正常,文件成功上传到服务器。 但是当在 iOS 设备(在我的例子中是 iPad)上执行时,正如我之前解释的那样,没有执行有关文件上传的处理程序,并且没有 http 请求事件命中服务器。所以我认为问题可能在客户端。
在尝试解决问题的过程中,我发现 iOS7 上的这个问题有些棘手。也就是说,如果在调用 File.upload 方法之前调用 URLLoader.load 方法(即使 URLLoader.load 指向一个不存在的地址),File.upload 将在 iOS7 上按预期工作。更具体地说,当上述方法 OnTrickyButtonPressed 在方法 OnUploadButtonPressed 之前执行时,iOS7 上的 File.upload 将成功。但这仅发生在 iOS7 上。在iOS8上,无论之前是否执行过URLLoader.load,File.upload总是拒绝工作。
我认为在我的情况下,问题不是下面两个链接中描述的沙盒问题或 Firefox 会话问题,因为甚至没有任何 http 请求到达服务器端。 Air SDK for iOS 似乎因为某种原因发送 http 请求失败。
Flex 4 FileReference Issues With Firefox
How do I make Flex file upload work on firefox and safari?
为了让我的问题更清楚,我在下面列出了我的环境:
- 开发环境:Windows7(64bit)/Mac os 10.9.4(测试于 两个操作系统平台。)
- IDE:Flash Builder 4.7
- Air SDK: 3.8 / 16.0.0 (在我更新到最新的Air SDK 16.0.0之后 ,问题依然存在。)
- 应用服务器:Tomcat7 + Spring
最后,我想提一下,在我的情况下,使用 URLLoader.load 上传文件不是一个选项,因为我想在将来上传大文件,而 URLLoader.load 无法处理。
我已经为此苦苦挣扎了好几天。因此,如果有人对此有任何想法,我将不胜感激。 提前致谢。
【问题讨论】:
-
如果你真的被这个问题困扰,你可以制作一个代表这个问题的小项目,然后上传到某个地方。我从来没有遇到过 file.upload 的问题
-
亲爱的德米特里,非常感谢您的回复。我会做一个小项目并尽快上传。谢谢。
-
亲爱的 Dmitry,我已经在以下地址上传了 flex 项目文件 SimpleFileUpload.fxp。 https://github.com/bluewindjava8/actionscript_file_upload_for_ios 。我真的很感谢你的帮助。非常感谢。 (我只上传客户端代码,因为在我的情况下,问题是客户端没有将请求发送到服务器。所以服务器端看起来不重要。)等待您的回复。跨度>
-
客户端没问题,我明天看这段代码
-
亲爱的德米特里,非常感谢。
标签: ios actionscript-3 flash apache-flex air