有很多示例:如何在Node.JS中使用Watson服务,但如果您使用REST API进行HTTP调用,我会遇到授权问题。
API的documentation告诉命令行 curl 界面, 但是,对于网络或混合应用程序使用javascript , HTTP调用没有具体示例。
在我的情况下,我想在Cordova Mobile APP中使用Watson Text2Speech,为此我将建立一个工厂。
我使用的http调用适用于其他API,但我在这里做错了什么? 任何遗漏的格式?
有人可以帮忙吗?
看起来像这样:
.factory('GetSpeech', ['$http','$cordovaDialogs','$cordovaMedia','Base64', function($http,
$cordovaDialogs,
$cordovaMedia,
Base64){
// http://ngcordova.com/docs/plugins/media/
// https://www.ibm.com/watson/developercloud/doc/speech-to-text/input.shtml
// https://www.npmjs.com/package/cordova-plugin-speech-recognition-feat-siri
var watson_url = "https://stream.watsonplatform.net/text-to-speech/api/v1/synthesize";
var watson_token_url = "https://stream.watsonplatform.net/authorization/api/v1/token?url=https://stream.watsonplatform.net/text-to-speech/api";
var watson_token = "";
var username='YOUR_KEY';
var password='YOUR_PW';
var authdata = 'Basic ' + Base64.encode(username + ':' + password);
console.log(">>> Watson - authdata: ",authdata);
var the_get_header = "{'Authorization':'"+ authdata +"','Content-Type':'application/json'}";
var message = "";
var getSpeech_innner = function (){ $http({method: 'GET',
url: watson_token_url,
headers: the_get_header
}).then( function successCallback(response) {
console.log(">>> GetToken Success:",response);
watson_token=response;
var the_post_header = "{'X-Watson-Authorization-Token':'"+ watson_token +"','Content-Type':'application/json','Accept':'audio/wav'}";
var the_post_text = JSON.stringify({ "text":"This is the first sentence of the paragraph. Here is another sentence. Finally, this is the last sentence."
});
$http({
method: 'POST',
url: watson_url,
headers: the_post_header,
data: the_post_text
}).then(function successCallback(response) {
// this callback will be called asynchronously
// when the response is available
console.log(">>> GetSpeech Success:",response);
message = "Success: " + response;
alert(message);
return true;
}, function errorCallback(response) {
// called asynchronously if an error occurs
// or server returns response with an error status.
console.log(">>> GetSpeech Error:",response);
message = "Error: " + response;
alert(message);
return false;
})
}, function errorCallback(response) {
console.log(">>> GetToken Error:",response);
});
};
return {
getSpeech : getSpeech_innner
};
}])
注意:顺便说一下,邮递员会调用HTTP。 GET令牌和 POST合成。
答案 0 :(得分:1)
我也尝试过类似的方法:
$http({
method: 'POST',
url: tts_url,
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers': 'access-control-allow-headers, Authorization',
'content-type': 'application/json',
'Authorization': 'Basic <base64(uid:password)>',
'Accept': 'audio/wav'
},
data: {'\"text\"': '\"hello world\"' },
output: 'hello_world.wav'
}).then(function successCallback(response) {
console.log(">>> Success:",response.status);
}, function errorCallback(response) {
console.log(">>> Error:", response.status);
});
我会收到此错误:
阻止跨源请求:同源策略禁止读取 远程资源在 https://stream.watsonplatform.net/text-to-speech/api/v1/synthesize。 (原因:在CORS标头中缺少令牌'access-control-allow-headers' 来自CORS预检频道的“Access-Control-Allow-Headers”。
当我删除“Access-Control-Allow-Headers”标题中的“access-control-allow-headers”条目时,行为是相同的......
在邮递员中运行相同的工作正常。
如何允许我的cordova应用程序呼叫远程资源?
答案 1 :(得分:1)
您是否已将Cordova应用程序中的stream.watsonplatform.net
来源列入白名单?在我看来,域名被阻止了。有关白名单的详细信息:https://cordova.apache.org/docs/en/latest/guide/appdev/whitelist/
答案 2 :(得分:1)
我的情况我想直接从服务经纪人获取令牌。
目前情况似乎是与 text2speech服务进行通信,我需要额外的服务器应用,例如在 Node.JS Server上运行< / strong>,为 cordova app 客户端提供令牌。
文档中提供了服务器令牌应用的示例代码。
这在使用令牌的主题编程模型一章中有记录。 Watson Documentation Link
这与沃森服务的开发模型有关。 原因是允许Postman和CURL调用,Web或移动应用程序的其他请求不是有效的Origins。
因此,您可以不直接从移动应用程序或Web应用程序使用REST API。同样的情况是使用Watson IoT。 这就是我使用Browserify Sample GitHub Project: browserfied-ibmiotf-webapplication
在Angular Web App中使用节点框架的原因为了更好地理解Watson API文档中的一张图片。 这在使用令牌的主题中的编程模型一章中有记录。 Watson Documentation Link
@Thanks 给Rene和Andrew指出了我的方向。
现在我有一个使用Text2Speech的有效的cordova应用程序。 我不在此示例中使用令牌,语音直接从Node.JS服务器提供给移动应用程序。
@感谢给Andrii,提供一些代码来执行此操作。
Node.JS服务器:
app.get('/getText2SpeechOutput', function (req, res) {
console.log(' -> text function called');
console.log(' calling watson to synthesize -> ', req.header('synthesize-text'));
var text_to_speech_l = new Text2speech({
username: req.header('service-username'),
password: req.header('service-password'),
});
var params = {
text: req.header('synthesize-text'),
voice: 'en-US_AllisonVoice',
accept: 'audio/wav'
};
var tempaudio = text_to_speech_l.synthesize(params);
console.log(' response received from Watson');
var reader = new wav.Reader();
reader.on('format', function (format) {
console.log(' file read success');
var writer = new wav.FileWriter('output.wav', {
channels: 1,
sampleRate: 22050,
bitDepth: 16
});
reader.pipe(writer);
console.log(' file write success');
writer.pipe(res)
console.log(' <- response provided');
});
tempaudio.pipe(reader);
})
Cordova App:
var getSpeech_innner = function (thetext, callback){
//const fileTransfer = new FileTransfer();
var headers = {
"Authorization": authdata,
"Accept": "audio/wav",
"synthesize-text": thetext,
"service-username": username,
"service-password": password
};
var options = {
headers: headers,
replace: true
};
$cordovaFileTransfer.download(get_speech_url , cordova.file.dataDirectory + 'speech.wav', options, true).then(
function (FileEntry) {
console.debug('>>> Success', FileEntry);
var filePath = cordova.file.dataDirectory + 'speech.wav';
callback(filePath);
},
function (error) {
console.debug('>>> download failure', error);
callback(error);
});
};