从 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
代替URLLoader
。 URLStream
也不关心安全问题。如果它们存在,它只会获取字节。根据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 文档转换时)