我尝试使用Windows Azure的非常基本的API调用来翻译一些文本。他们给出了快速启动示例代码。
我尝试此代码,并且效果很好。文本Hello world
被翻译成Deutch和Italian。
我删除了我的个人订阅密钥。
这是示例:
const request = require('request');
const uuidv4 = require('uuid/v4');
const subscriptionKey = '........';
let options = {
method: 'POST',
baseUrl: 'https://api.cognitive.microsofttranslator.com/',
url: 'translate',
qs: {
'api-version': '3.0',
'to': ['de', 'it']
},
headers: {
'Ocp-Apim-Subscription-Key': subscriptionKey,
'Content-type': 'application/json',
'X-ClientTraceId': uuidv4().toString()
},
body: [{
'text': 'Hello World!'
}],
json: true,
};
request(options, function(err, res, body){
console.log(JSON.stringify(body, null, 4));
});
看起来此代码是node
的服务器端库。现在,我需要将此代码集成到我的[Aurelia] [2]应用程序中。因此,我考虑使用aurelia-fetch-client
替换request
方法。我使用Aurelia Cli。
这是我所做的:
添加在package.json中:
"dependencies": {
....
"@types/uuidv4": "^2.0.0",
...
"uuidv4": "^4.0.0",
}
在Aurelia.json中添加:
"dependencies": [
...
"uuidv4"
]
在我的控制台内运行npm install
。
创建了一个测试页面:
import { HttpClient, json } from 'aurelia-fetch-client';
import { autoinject } from 'aurelia-framework';
import * as uuidv4 from 'uuidv4';
import secret from '../secret';
@autoinject
export class Translator {
constructor(httpClient: HttpClient) {
this.httpClient = httpClient;
}
private httpClient: HttpClient;
private translate(from, to, html) {
debugger;
var init: RequestInit =
{
method: 'POST',
//mode: 'no-cors',
headers: {
'Ocp-Apim-Subscription-Key': secret.translatorKey,
'Content-type': 'application/json',
//'Content-Type': 'application/x-www-form-urlencoded',
'X-ClientTraceId': uuidv4().toString()
},
credentials: 'same-origin',
body: $.param({
'api-version': '3.0',
'from': 'en',
'to': 'fr',
'text': '<b>Hello World!</b>' })
//body: json({ 'text': '<b>Hello World!</b>' })
};
this.httpClient.fetch(`https://api.cognitive.microsofttranslator.com/`, init)
.then((result) => {
debugger;
})
.catch((error) => {
debugger;
});
}
诀窍是能够将选项传递给示例代码的request
并将其调整为aurelia-fetch-client
。我没有成功。
不幸的是,我总是在下面遇到错误:
访问'https://api.cognitive.microsofttranslator.com/'来自Origin'http://localhost:9000'已被CORS策略阻止访问控制检查:不允许重定向以进行前飞行请求。
有什么建议?
tl; dr - 就像您一样,我很难从浏览器中工作的文档中获取说明。但是,将 Subscription-Key
附加为querystring参数似乎确实有效。
示例,请阅读评论:
import { HttpClient } from 'aurelia-fetch-client';
import { autoinject } from 'aurelia-framework';
@autoinject
export class App {
constructor(private http: HttpClient) {
}
private async attached(): Promise<void> {
// Important: use either key1 or key2, not the guid from your subscription
const subscriptionKey = 'YOUR-KEY-HERE';
// Important: the endpoint is different per GEO-REGION
const baseUrl = 'https://api-eur.cognitive.microsofttranslator.com';
const body = [{
'text': 'Hello World!'
}];
// Note: I couldn't get 'Ocp-Apim-Subscription-Key' working in the browser (only through Postman, curl)
// Also, trading in the subscriptionKey for a Bearer token did not work for me (in the browser)
// Therefor, we append it to the url later on.
// Also notice, X-ClientTraceId' is NOT neccessary and the docs don't explain why it's needed
const headers = new Headers();
headers.append('Content-Type', 'application/json');
const response = await this.http.fetch(`${baseUrl}/translate?api-version=3.0&to=nl&Subscription-Key=${subscriptionKey}`, {
method: 'POST',
headers: headers,
body: JSON.stringify(body)
});
if (response.ok) console.log(await response.json());
}
}
请注意,在此示例中,您不需要request
和uuid
库。您只需要:
$ npm install --save aurelia-fetch-client whatwg-fetch
我还注意到您正在使用Typescript,因此更改了使用@autoinject
使用的示例。
较长的故事
如果您获得了很多401的功能 - 有一个较旧的MSDN博客文章,它绝对值得一读。一些亮点:
- 根据您的Azure服务的地理位置,有不同的API端点。
- 单个服务(翻译器,视觉等(之间的终点存在差异,这些服务是基于地理区域的 - 和通用,更广泛的认知服务(又称认知多服务订阅(。
- 如果您使用的是单个服务,则每个服务的API密钥不同。
- 有3种不同的认证方式;但是,我只能让其中一个在浏览器中工作。
这也或多或少地写在官方文档中。
话虽如此,文档中的示例并不好。最起码,我是这么想的。首先,您想确保确切知道应该做什么。这是一个卷曲示例:
curl -X POST
'https://api-eur.cognitive.microsofttranslator.com/translate?api-version=3.0&to=nl'
-H 'Content-Type: application/json'
-H 'Ocp-Apim-Subscription-Key: <YOUR-KEY-HERE>'
-d '[{
'''text''': '''Hello World!'''
}]'
虽然听起来很容易,但我无法在浏览器中正常工作,在那里我继续获得401的CORS问题。原因似乎是因为它没有吞下" OCP-Apim-Subscription-key"。我还尝试在订阅中进行交易以获取授权携带者令牌(示例(,该授权人也不在浏览器中使用。这些示例确实在卷曲中或邮递员中起作用。
最后,只是回到使用订阅键,作为querystring有所帮助。至少对我而言。
希望这会有所帮助!