IBM Watson 服务尚不支持从基于浏览器的应用程序获取跨源请求。
答案见由于 Rails/AJAX 应用程序上的 CORS,无法在本地访问 IBM Watson API:
我们不支持 CORS,我们正在努力解决它,但在您的情况下,尚不支持视觉识别。
这意味着某些服务支持 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-*
标题是response标头,而不是请求标头;在请求中将它们发送到服务器对 CORS 没有影响,因为如上所述,浏览器是 CORS 执行点,而不是服务器。
因此,服务器不会从浏览器收到一些请求并说,好吧,我看到这个请求有正确的标头,所以我会允许它。相反,服务器允许来自浏览器的所有请求,就像它允许来自非浏览器工具(例如 Java 代码、curl 或 Postman 或其他工具)的所有请求一样(当然只要它们经过身份验证)并发送响应。
不同之处在于,当非基于浏览器的应用程序收到响应时,如果缺少响应,它不会拒绝您访问该响应Access-Control-Allow-Origin
标头。但如果缺少响应,浏览器确实会拒绝让您的客户端 JavaScript Web 应用程序代码访问响应。