【问题标题】:ActionScript's File.upload does not work on Air SDK for iOS devicesActionScript 的 File.upload 不适用于 iOS 设备的 Air SDK
【发布时间】: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


【解决方案1】:

最后我发现真正的问题不是我提供的代码,而是http代理自动配置的问题,而且这个问题发生在iOS7和iOS8上。我在以下链接中详细描述了问题和解决方法。希望这会对你们中的一些人有所帮助。

https://forums.adobe.com/thread/1716036

【讨论】:

    猜你喜欢
    • 2013-04-18
    • 2015-11-28
    • 1970-01-01
    • 1970-01-01
    • 2021-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多