如何从 javascript 调用 IBM Watson 服务



我正在使用 IBM Watson 服务实现一个虚拟代理。我的应用程序是使用 Jquery、Angular JS 和 Java 开发的,目前我正在从中间层(即 java)调用 Watson 服务。但我想避免这种情况,直接从javascript调用。当我使用 XML Http 请求从 javascript 调用时,我收到 CORS 错误。如何解决这个问题?

下面是我的代码:

var username = "uid";
var password = "pwd";
var xhr = new XMLHttpRequest();
xhr.open('GET', 'url');
//xhr.withCredentials = true;
xhr.setRequestHeader("Access-Control-Allow-Headers", "Access-Control-Allow-Origin,Content-Type, application/json, Authorization");
xhr.setRequestHeader("Access-Control-Allow-Origin", "*");
xhr.setRequestHeader('Access-Control-Allow-Credentials', '*');
xhr.setRequestHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
xhr.setRequestHeader('Content-Type', undefined);
xhr.setRequestHeader('Authorization', 'Basic ' + btoa(username + " " + password));
xhr.send('"query":"hi"');

IBM Watson 服务尚不支持从基于浏览器的应用程序获取跨源请求。

在 Curs/AJAX App 上,由于 CORS on a Rails/AJAX App 无法在本地访问 IBM Watson API 中查看答案:

我们不支持 CORS,我们正在研究它,但在您的情况下,尚不支持视觉识别。

这意味着某些服务支持 CORS,但我想您尝试过的服务不是其中之一。

因此,除了您现在所说的(从服务器端Java层访问服务)之外,从Web应用程序中运行的JavaScript代码获取服务的唯一选择是,使用 https://github.com/Rob--W/cors-anywhere 等设置自己的服务器端代理,或者通过像 https://cors-anywhere.herokuapp.com/这样的开放CORS代理发送请求(尽管在您的请求包含任何类型的您不希望向第三方代理服务的运营商公开的身份验证令牌)。

此类代理的工作方式是,不要使用 https://gateway.watsonplatform.net/some/api 作为在客户端 JavaScript 代码中指定的请求 URL,而是指定代理 URL,如 https://cors-anywhere.herokuapp.com/https://gateway.watsonplatform.net/some/api,代理将实际请求发送到服务,获取响应,并将所需的Access-Control-Allow-Origin响应标头和其他标头添加到其中并传递它。

因此,包含 CORS 标头的响应是浏览器看到的。

https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS 提供了有关 CORS 工作原理的更多详细信息,但要知道的主要事情是浏览器是 CORS 实施点。因此,在 Watson 服务的情况下,浏览器实际上将从 Watson API 获得响应 — 您将能够使用浏览器中的 devtools 来查看响应 — 但只有当响应包含Access-Control-Allow-Origin响应标头以指示发送响应的服务器已选择接收来自运行在网络应用。

因此,这就是为什么无论如何,上面 XHR 代码片段中的所有xhr.setRequestHeader("Access-Control-Allow-行都需要删除 — 因为Access-Control-Allow-*标头是响应标头,而不是请求标头;在请求中将它们发送到服务器对 CORS 没有影响,因为如上所述,浏览器是 CORS 实施点,而不是服务器。

因此,服务器不会从浏览器收到一些请求并说,好吧,我看到此请求具有正确的标头,所以我会允许它。相反,服务器允许来自浏览器的所有请求,就像它允许来自非浏览器工具(如Java代码或curl或Postman之类的)的所有请求(当然,只要它们经过身份验证)并发送响应一样。

不同之处在于,当非基于浏览器的应用程序收到响应时,如果它缺少Access-Control-Allow-Origin标头,它不会拒绝让您访问响应。但是浏览器确实拒绝让你的客户端JavaScript Web应用程序代码访问响应,如果它缺乏它。

您可能还想查看GitHub上提供的一些Watson SDK。

一些 Watson 服务支持 CORS,而其他则不支持。但是,通过 CORS 访问时,必须使用身份验证令牌而不是用户名/密码组合*。

这是哪些服务支持 CORS 的部分列表:https://github.com/watson-developer-cloud/node-sdk/tree/master/examples/webpack#important-notes

以下是使用 Node.js SDK 的几个示例:

  • 网络包: https://github.com/watson-developer-cloud/node-sdk/tree/master/examples/webpack
  • 浏览器化:https://github.com/watson-developer-cloud/node-sdk/tree/master/examples/browserify

此外,还有一大堆使用语音JavaScript SDK的示例:

  • https://watson-speech.mybluemix.net/

* 有几个服务使用 API 密钥而不是用户名/密码组合。在这种情况下,如果服务支持 CORS,则可以直接从客户端代码使用 API 密钥。

看看这个关于使用 Watson 问答服务的 IBM developerWorks 教程 - http://www.ibm.com/developerworks/cloud/library/cl-watson-qaapi-app/index.html#N10229

最新更新