如何从javascript调用IBM Watson服务

use*_*957 3 javascript java jquery cors 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"');
Run Code Online (Sandbox Code Playgroud)

sid*_*ker 6

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/(尽管您不太可能'如果您的请求包含您不希望向第三方代理服务的运营商公开的任何类型的身份验证令牌,那么我们希望这样做.

这种代理的工作方式是,而不是使用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代码段中的所有行都需要被删除 - 因为Access-Control-Allow-*标题是响应头,而不是请求头; 将它们发送到服务器请求对CORS没有影响,因为如上所述,浏览器是CORS执行点,而不是服务器.

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

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