使用 Aurelia 的 Fetch Client 时 Azure Translator API(认知服务)上出现 CORS 错误

2023-12-28

我尝试使用来自 Windows Azure 的非常基本的 API 调用来翻译一些文本。他们给出了一个快速入门示例代码 https://learn.microsoft.com/en-us/azure/cognitive-services/translator/quickstart-nodejs-translate.

我尝试了这段代码,效果很好。文本Hello world被翻译成德语和意大利语。

我删除了我的个人订阅密钥。

这是示例:

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"
]

Run 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/ https://api.cognitive.microsofttranslator.com/'从原点'http://本地主机:9000 http://localhost:9000' 已被 CORS 策略阻止:对预检请求的响应未通过访问控制检查:预检请求不允许重定向。

有什么建议 ?


TL;DR- 就像您一样,我很难从浏览器中工作的文档中获取说明。然而,附加Subscription-Key因为查询字符串参数似乎确实有效。

示例,请阅读评论:

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 and uuid图书馆。您只需要:

$ npm install --save aurelia-fetch-client whatwg-fetch

我还注意到您正在使用 TypeScript,因此更改了示例以使用它@autoinject.

更长的故事

如果您收到很多 401 - 有一个较旧的 MSDN 博文 https://blogs.msdn.microsoft.com/kwill/2017/05/17/http-401-access-denied-when-calling-azure-cognitive-services-apis/这仍然绝对值得一读。一些亮点:

  • 不同的API端点 https://learn.microsoft.com/en-us/azure/cognitive-services/translator/reference/v3-0-reference#base-urls取决于 Azure 服务的地理位置。
  • 基于地理区域的各个服务(翻译器、视觉等)与通用的、更广泛的认知服务(又称认知服务)之间的端点存在差异。多服务订阅).
  • 如果您使用的是单独的服务,则每个服务的 API 密钥都不同。
  • 有 3 种不同的身份验证方式;但是,我只能让其中之一在浏览器中工作。

这也或多或少写了在官方文档中 https://learn.microsoft.com/en-us/azure/cognitive-services/translator/reference/v3-0-reference.

话虽这么说,文档中的示例实际上并没有什么好处。最起码,我是这么想的。首先,您要确保您确切地知道自己应该做什么。这是一个卷曲示例:

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”。我还尝试过用 subscriptionKey 换取授权持有者令牌(example https://learn.microsoft.com/en-us/azure/cognitive-services/translator/reference/v3-0-reference#authorization-token)这在浏览器中也不起作用。这些示例在curl 或Postman 中确实有效。

最后,重新使用 SubscriptionKey 作为查询字符串会有所帮助。至少对于我来说。

希望这可以帮助!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Aurelia 的 Fetch Client 时 Azure Translator API(认知服务)上出现 CORS 错误 的相关文章

随机推荐