2017-10-04 16 views
1

액션 스크립트 3 플래시 애플리케이션을 통해 왓슨 텍스트 to 스피치 API에 액세스하려고합니다. Adobe는 규칙 기반 XML 구성 파일 (crossdomain.xml)을 사용하는 메커니즘을 사용하여 도메인 간 액세스를 제한하는 새로운 보안 기능을 구현 한 것으로 알고 있습니다. 스크립트가 실행될 때 내 경우에는 아래의 오류가 발생합니다 :어도비 액션 스크립트 3의 왓슨 API 액세스

소스 코드 :

 

    package 
    { 
     import flash.net.URLRequest; 
     import flash.net.URLRequestHeader; 
     import flash.net.URLLoaderDataFormat; 
     import flash.net.URLLoader; 
     import flash.net.URLVariables; 
     import flash.net.URLRequestMethod; 
     import flash.events.Event; 
     import flash.events.HTTPStatusEvent; 
     import flash.events.SecurityErrorEvent; 
     import flash.events.IOErrorEvent; 

     public class Greeter 
     { 
     public function sayHello():String 
     { 

      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 = "application/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); 

      try 
      { 
      postLoader.load(request); 
      } 
      catch (error:Error) 
      { 
      trace("Unable to load post URL"); 
      } 

      var greeting:String; 
      greeting = "Prueba de conexión a Watson!"; 
      return JSON.stringify(request.data); 
     } 

     private function loaderCompleteHandler(event:Event):void 
     { 
      trace("loaderCompleteHandler: "); 
     } 

     private function httpStatusHandler(event:HTTPStatusEvent):void 
     { 
      trace("httpStatusHandler: "); 
     } 

     private function securityErrorHandler(event:SecurityErrorEvent):void 
     { 
      trace("securityErrorHandler: " + event); 
     } 

     private function ioErrorHandler(event:IOErrorEvent):void 
     { 
      trace("ioErrorHandler: " + event); 
     } 
     } 
    } 

콘솔 출력 :

 

[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 conexió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 
[trace] 05:45:44 PM | err | [SecurityErrorEvent type="securityError" bubbles=false cancelable=false eventPhase=2 text="Error #2170: Security sandbox violation: http://garragames.com/garra-x/Tick.swf cannot send HTTP headers to https://watson-api-explorer.mybluemix.net/text-to-speech/api/v1/voices."] 
[trace] Error #2044: Unhandled securityError:. text=Error #2170: Security sandbox violation: http://garragames.com/garra-x/Tick.swf cannot send HTTP headers to https://watson-api-explorer.mybluemix.net/text-to-speech/api/v1/voices. 

가 ¿ 액션 스크립트 플래시에서 API에 액세스 할 수있는 다른 옵션을 존재 앱?

+4

** 옵션 1 **. 일부 서비스는 플래시 보안 모델을 염두에두고 기능을 사용하는 수단을 제공합니다. 해당 설명서를 읽거나 지원 부서에 문의하십시오. ** 옵션 2 **. 웹 기반 응용 프로그램이 아니더라도 AIR를 사용하십시오. 데스크톱/모바일 애플리케이션은 제한이 적습니다. ** 옵션 3 **. 언제든지 귀하의 앱에 의지 할 수 있습니다 ** <-> ** 귀하의 서버 ** <-> ** 그들의 서비스 모델. – Organis

+0

이 오류를 다시 작성하기 위해 테스트 할 수있는 일부 코드를 표시하십시오. 어쩌면 누군가 그것을 고칠 수 있습니다. –

+0

@Garrapato, PHP는 데이터에 액세스하고 AS3에 전달하는 옵션입니까? 보안 오류는 사이트가 'http : //'이지만 'https : //'사이트에서 미디어를로드하려고 시도했기 때문입니다. 그것 (보안/HTTPS 서버를 사용 함으로서)을 고치더라도, 당신은 실제 에러를 얻을 것입니다 :'인가 헤더는 Actionscript'에서 허용되지 않습니다. PHP 또는 자바 스크립트 중 하나를 사용하고 .. 외부 인터페이스를 통해 AS3에 내가 HTTPS 프로토콜을 테스트합니다 –

답변

0

당신의 진짜 문제는 "가 인증하는 방법?"해야 아니라 (자동 크로스 도메인 확인이있는) URLLoader를 통해 디코딩 /로드의 보안 샌드 박스 문제를 이길 방법에 비해 플래시에서 왓슨의 API와.

어떻게 든 인증 (로그인)해야합니다. 이것은 Actionscript를 통해서만 얻을 수있는 것 같지 않습니다. URLStream 대신 URLLoader를 사용하여

"Authorization header cannot be sent using Actionscript" 

: 당신은 같은 플래시 플레이어 오류를 볼 수 있습니다. 또한 URLStream은 보안 문제에 대해 신경 쓰지 않습니다. 바이트가 있으면 그냥 가져옵니다. this document에 따르면 플래시 권한 요청이 허용됩니다. 그래도 나를 위해 일하지 않았어. 어쩌면 디버거에서 허용되지 않을 수 있습니까?

URL/도메인에서 인증되면 Flash 응용 프로그램은 동일한 (현재 허용 된) 도메인을 통해 묻기 때문에 보통 POST url로 요청을 할 수 있습니다. 도메인 간 제한 사항이 없으므로 바이트를 원하면 URLLoader 대신 URLStream을 사용하십시오.

PS : 예를 들어 Sound 개체를 사용하여 음성으로 변환 된 텍스트를 재생할 수 있습니다.

( authenticated 경우, 즉 : 당신이 로그인) : 인스턴스 이름 txtbox으로,

  • 이 스테이지에서 input 텍스트 상자를 확인하십시오. 라는 문서 클래스의 코드를 아래
  • 저장 : Main.as은 (Main.swf로 컴파일)

테스트 아래의 코드 : (SWF 결과 = 텍스트 상자를 눌러 타입으로는이 말을 듣고 입력).

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" width="800" height="600"> 

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

    </body> 
    </html>