javascript - 如何从 javascript 调用 IBM Watson 服务

标签 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"');

最佳答案

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

Can't access IBM Watson API locally due to CORS on a Rails/AJAX App 查看答案:

We don't support CORS, we are working on it but in your case Visual Recognition is not supported yet.

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

因此,除了您所说的您现在正在做的事情(改为从您的服务器端 Java 层访问服务)之外,您从 Web 应用程序中运行的 JavaScript 代码获取服务的唯一选择是,设置您的自己的服务器端代理 https://github.com/Rob--W/cors-anywhere之类的,或者通过一个开放的 CORS 代理发送你的请求,比如 https://cors-anywhere.herokuapp.com/ (尽管如果您的请求包含您不想暴露给第三方代理服务运营商的任何类型的身份验证 token ,您不太可能希望这样做)。

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

因此浏览器看到的是包含 CORS header 的响应。

https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS有更多关于 CORS 工作原理的细节,但要知道的主要事情是浏览器是 CORS 的执行点。因此,在使用 Watson 服务的情况下,浏览器实际上将从 Watson API 获取响应——您将能够在浏览器中使用 devtools 来查看响应——但浏览器会将响应公开给您的客户端 JavaScript 代码仅当响应包含 Access-Control-Allow-Origin 响应 header 以指示发送响应的服务器已选择接收来自 Web 应用程序中运行的客户端 JavaScript 的跨域请求时。

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

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

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

关于javascript - 如何从 javascript 调用 IBM Watson 服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43105146/

相关文章:

javascript - Node.JS:事件发射器

javascript - 使用纯 JavaScript 获取 iframe 的内容

java - 向 Java Swing 容器添加动画/过渡

java - 将查询字符串存储在数据库中通常被认为是可行的吗?

javascript - 使用 javascript 和 php 从数据库获取数据

java - Spring oauth2 - 授权服务和globalUserDetails之间的区别

javascript - 单击时禁用提交按钮太慢,延迟

jQuery DataTable - 动态初始化后隐藏/显示启用/禁用列过滤

javascript - 减少 jquery 选择器获得的结果

javascript - Json服务器: Error: Insert failed,重复ID