从 adobe 操作脚本 3 访问 Watson API

Posted

技术标签:

【中文标题】从 adobe 操作脚本 3 访问 Watson API【英文标题】:Watson API access from adobe action script 3 【发布时间】:2018-03-16 11:55:40 【问题描述】:

我正在尝试通过操作脚本 3 flash 应用程序访问 Watson Text to Speech API。如您所知,Adobe 使用基于规则的 xml 配置文件 (crossdomain.xml) 的机制实施了一项新的安全功能,以限制跨域的访问。在我的情况下,执行脚本时会引发以下错误:

源代码:

包裹 导入 flash.net.URLRequest; 导入 flash.net.URLRequestHeader; 导入 flash.net.URLLoaderDataFormat; 导入 flash.net.URLLoader; 导入 flash.net.URLVariables; 导入 flash.net.URLRequestMethod; 导入 flash.events.Event; 导入 flash.events.HTTPStatusEvent; 导入 flash.events.SecurityErrorEvent; 导入 flash.events.IOErrorEvent; 公共课迎宾员 公共函数sayHello():字符串 var params:Object = user:"John",password:"secret"; var request:URLRequest = new URLRequest(); request.url = "https://watson-api-explorer.mybluemix.net/text-to-speech/api/v1/voices"; request.contentType = "应用程序/json"; request.method = URLRequestMethod.POST; request.data = JSON.stringify(params); var contentTypeHeader:URLRequestHeader = new URLRequestHeader("Content-Type","application/json"); var acceptHeader:URLRequestHeader = new URLRequestHeader("Accept","application/json"); var formDataHeader:URLRequestHeader = new URLRequestHeader("Content-Type","application/json"); var authorizationHeader:URLRequestHeader = new URLRequestHeader("Authorization","Basic YjcxYWUwNTMtZTJmYi00ZmQzLWFiMTctOTRjYTc2MzYzYWE3OlZ5dU9VZ0w3ak1zVw=="); request.requestHeaders = [acceptHeader,formDataHeader,authorizationHeader,contentTypeHeader]; var postLoader:URLLoader = new URLLoader(); postLoader.dataFormat = URLLoaderDataFormat.BINARY; postLoader.addEventListener(Event.COMPLETE, loaderCompleteHandler); postLoader.addEventListener(HTTPStatusEvent.HTTP_STATUS, httpStatusHandler); postLoader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler); postLoader.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler); 尝试 postLoader.load(请求); 捕捉(错误:错误) trace("无法加载帖子 URL"); 变量问候:字符串; Greeting = "Prueba de conexión a Watson!"; 返回 JSON.stringify(request.data); 私有函数 loaderCompleteHandler(event:Event):void trace("loaderCompleteHandler:"); 私有函数 httpStatusHandler(event:HTTPStatusEvent):void trace("httpStatusHandler:"); 私有函数securityErrorHandler(事件:SecurityErrorEvent):无效 trace("securityErrorHandler:" + event); 私有函数 ioErrorHandler(event:IOErrorEvent):void trace("ioErrorHandler:" + 事件);

控制台输出:

[trace] Advertencia: Error al cargar el archivo de política desde https://watson-api-explorer.mybluemix.net/crossdomain.xml [trace] *** Violación de la seguridad Sandbox *** [trace] Se ha detenido la conxión con https://watson-api-explorer.mybluemix.net/text-to-speech/api/v1/voices - no se permite desde http://garragames.com/garra-x /tick.swf [追踪] 05:45:44 PM |错误 | [SecurityErrorEvent type="securityError" bubbles=false cancelable=false eventPhase=2 text="错误 #2170: 安全沙箱违规:http://garragames.com/garra-x/Tick.swf 无法将 HTTP 标头发送到 https:// /watson-api-explorer.mybluemix.net/text-to-speech/api/v1/voices."] [trace] 错误 #2044:未处理的安全错误:。 text=Error #2170:违反安全沙箱:http://garragames.com/garra-x/Tick.swf 无法将 HTTP 标头发送到 https://watson-api-explorer.mybluemix.net/text-to-speech/ api/v1/声音。

¿是否存在从 Action Script Flash 应用程序访问 API 的其他选项?

【问题讨论】:

选项 1。一些服务考虑到了 Flash 安全模型,并提供了使用其功能的方法。阅读他们的文档或联系他们的支持。 选项 2。如果您不需要它是基于 Web 的应用程序,请使用 AIR。桌面/移动应用程序的限制较少。 选项 3。你总是可以求助于你的应用你的服务器他们的服务模型。 显示一些可以测试重新创建此错误的代码。也许有人可以解决它。 @Garrapato,php 是访问数据并传递给 AS3 的选项吗?您的安全错误是因为您的站点是 http://,但您尝试从 https:// 站点加载媒体。即使你修复了这个问题(通过使用安全/HTTPS 服务器),你也会得到真正的错误:Authorization header is not allowed in Actionscript。使用 PHP 或 javascript 并通过外部接口将数据传递给 AS3.. 我将使用https协议进行测试,但是根据adobe文档,IBM Watson Team应该在根目录中放置一个带有规则的crossdomain.xml文件,以允许从我的域进行远程访问。跨度> 我刚刚尝试使用来自 garragames.com 的 https 协议,结果相同:
[trace] Advertencia: Error al cargar el archivo de política desde watson-api-explorer.mybluemix.net/crossdomain.xml [trace] ** * Violación de la seguridad Sandbox *** [trace] Se ha detenido la conxión con watson-api-explorer.mybluemix.net/text-to-speech/api/v1/voices/… - no se permite desde garragames.com/garra-x/Tick.swf 
【参考方案1】:

您真正的问题应该是如何使用 Flash 中的 Watson API 进行身份验证?,而不是如何通过 URLLoader 解决加载/解码的安全沙盒问题(具有自动跨域检查)。

您必须以某种方式进行身份验证(登录)。这似乎不太可能仅通过 Actionscript 实现。您可以看到 Flash Player 错误,例如:

"Authorization header cannot be sent using Actionscript"

使用URLStream 代替URLLoaderURLStream 也不关心安全问题。如果它们存在,它只会获取字节。根据this document,它说允许Flash“授权”请求。虽然没有为我工作。也许它在调试器中是不允许的?

一旦通过您的 URL/域进行身份验证,您的 Flash 应用程序也可以像正常的 POST url 一样发出任何请求,因为它通过相同的(现在允许的)域进行请求。如果您需要字节,请使用 URLStream 而不是 URLLoader,因为它没有跨域限制。

PS:例如,您可以使用Sound 对象来播放转换为语音的文本。

(如果authenticated,即:您已登录)尝试:

在舞台上创建一个input 文本框,实例名称为txtbox。 将以下代码保存在名为 Main.as 的文档类中(编译为 Main.swf)

测试下面的代码:(SWF 结果 = 在文本框中输入并按 Enter 听到它的声音)。

    package  
    
        import flash.display.MovieClip;
        import flash.utils.*;
        import flash.media.*;
        import flash.net.*;
        import flash.events.*;

        public class Main extends MovieClip 
        
            public var snd_Obj: Sound = new Sound; 
            public var snd_Chann: SoundChannel = new SoundChannel;
            public var snd_req: URLRequest = new URLRequest();

            public var str_Token: String = "";
            public var url_sendto_Watson: String = "";

            public var str: String = "";
            public var str_Voice: String = "";
            public var str_mySpeech: String = "";

            public var load_Token: URLLoader;

            public function Main() 
            
                load_Token = new URLLoader();
                load_Token.addEventListener(Event.COMPLETE, onTokenLoaded);
                load_Token.load(new URLRequest("https://stream.watsonplatform.net/authorization/api/v1/token?url=https://stream.watsonplatform.net/text-to-speech/api"));

                //# Your token as requested from :: https://stream.watsonplatform.net/authorization/api/v1/token?url=https://stream.watsonplatform.net/text-to-speech/api
                //trace("Token :  " + str_Token); //# To confirm it has token code

                //txtbox.type = "INPUT"; 
                txtbox.background = true; 
                txtbox.text = ""; //starting text
                txtbox.addEventListener(TextEvent.TEXT_INPUT, text_inputCapture);
                txtbox.addEventListener(KeyboardEvent.KEY_DOWN, key_handler);
                addChild(txtbox); 
            

            function key_handler(evt:KeyboardEvent)
            
                if(evt.charCode == 13) //# if ENTER key is pressed (will send text to convert to speech)
                
                    str_mySpeech = txtbox.text;
                    str_mySpeech = str_mySpeech.replace(" ", "%20");

                    str_Voice = "en-US_AllisonVoice"; //or your preferred voice (see: 

                    //# Update requested URL to include your typed text
                    url_sendto_Watson = ""; //# reset
                    url_sendto_Watson = "https://stream.watsonplatform.net/text-to-speech/api/v1/synthesize?";
                    url_sendto_Watson += "accept=audio/mp3"; //# get as MP3 result
                    url_sendto_Watson += "&text=" + str_mySpeech;
                    url_sendto_Watson += "&voice=" + str_Voice; //# ie: "en-US_AllisonVoice"
                    url_sendto_Watson += "&token=" + str_Token;

                    //# Attempt loading
                    snd_req.url = url_sendto_Watson;
                    snd_Obj = new Sound(); 
                    snd_Obj.addEventListener(Event.COMPLETE, onSoundLoaded);
                    snd_Obj.load( snd_req );

                    txtbox.removeEventListener(KeyboardEvent.KEY_DOWN, key_handler);
                
            

            public function text_inputCapture(event:TextEvent):void 
             
                str = txtbox.text;  //# Update text to send
                txtbox.addEventListener(KeyboardEvent.KEY_DOWN, key_handler); 
             

            function onSoundLoaded(event:Event):void 
             
                snd_Chann = snd_Obj.play(); //# Play returned Speech convert result
                snd_Obj.removeEventListener(Event.COMPLETE, onSoundLoaded);
            

            function onTokenLoaded(evt:Event):void 
             str_Token = evt.target.data; /*# get Token result */ 


         //end Class

     //end Package

这仅在 SWF 文件嵌入 html 页面时有效。如下所示:

    <!DOCTYPE html>
    <html>
    <body>

    <audio id="audio_watson">
    <source src="http://stream.watsonplatform.net/text-to-speech/api/v1/synthesize?accept=audio/mp3&text=welcome&voice=en-US_AllisonVoice" type="audio/mpeg">
    </audio>

    <embed src="Main.swf"  >

    <script>
    var a = document.getElementById("audio_watson");
    a.play(); //playback to trigger authentication
    </script>

    </body>
    </html>

【讨论】:

以上是关于从 adobe 操作脚本 3 访问 Watson API的主要内容,如果未能解决你的问题,请参考以下文章

无法解析代理:POST(在运行 curl 脚本进行 watson 文档转换时)

国外物联网平台初探:IBM Watson IoT

使用 Watson Discovery 访问可公开访问的 URL

Adobe Flash动作脚本3

从浏览器获取相同的会话到 Adob​​e

如何向 watson 对话响应添加操作?