如何从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服务尚不支持从基于浏览器的应用程序获取跨源请求。

由于Rails / AJAX应用程序上的CORS,请参阅本地无法访问IBM Watson API的答案:

我们不支持CORS,我们正在努力,但在您的情况下,目前还不支持Visual Recognition。

这意味着一些服务支持CORS,但我想你尝试的那个并不是其中之一。

所以除了你现在所说的(从服务器端Java层访问服务)之外,从Web应用程序中运行的JavaScript代码获取服务的唯一选择是设置自己的服务器 – 使用https://github.com/Rob–W/cors-anywhere等进行代理,或通过开放式CORS代理发送您的请求,例如https://cors-anywhere.herokuapp.com/ (尽管您不太可能’如果您的请求包含您不希望向第三方代理服务的运营商公开的任何类型的身份validation令牌,那么我们希望这样做。

这种代理的工作方式是,而不是使用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查看响应 – 但浏览器将向客户端JavaScript代码公开响应仅当响应包含Access-Control-Allow-Origin响应标头时,才表明发送响应的服务器已选择接收来自Web应用程序中运行的客户端JavaScript的跨源请求。

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

所以不是服务器从浏览器收到一些请求并且说,好的,我看到这个请求有正确的标题,所以我会允许它。 相反,服务器允许来自浏览器的所有请求,就像它允许来自非Java浏览器工具的所有请求,例如Java代码或curl或Postman或其他任何请求(只要它们经过身份validation)并发送响应。

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

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

一些Watson服务支持CORS,而其他服务则不支持。 但是,通过CORS访问时,您必须使用Auth Token而不是用户名/密码组合*。

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

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

  • Webpack: https : //github.com/watson-developer-cloud/node-sdk/tree/master/examples/webpack
  • Browserify: https : //github.com/watson-developer-cloud/node-sdk/tree/master/examples/browserify

并且,使用Speech JavaScript SDK的大量示例:

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

在IBM developerWorks上查看有关使用Watson问答服务的本教程 – http://www.ibm.com/developerworks/cloud/library/cl-watson-qaapi-app/index.html#N10229