How to call IBM Watson services from javascript

I am using a virtual agent using IBM Watson services. My application is developed using JQuery, Angular JS and Java. I am currently calling watson services from the middle tier, which is java. But I want to avoid this and call directly from javascript. When I call from javascript using XML Http request, I get CORS error. How to solve this problem?

Below is my code:

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

      

+3


source to share


4 answers


IBM Watson Services does not yet support receiving cross-origin requests from browsers.

See answer to Unable to access IBM Watson APIs locally due to CORS in Rails / AJAX application :

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

This implies that some of the services support CORS, but I think the one you tried is not one of them.

Other than what you say you are doing now (accessing services from your server side Java layer), your only way to access services from JavaScript code running in your web application is either by setting up your own -side proxy with https: / /github.com/Rob--W/cors-anywhere or such, or send your requests through a CORS open proxy like https://cors-anywhere.herokuapp.com/ (although it's unlikely that you would want to do this in the case of when your requests include some sort of authentication token that you don't want to show to the third party proxy service operator).

How do such proxies work, instead of using https://gateway.watsonplatform.net/some/api as the request url that is specified in your client-side JavaScript, you instead specify the proxy url like https: // cors-anywhere.herokuapp.com/https://gateway.watsonplatform.net/some/api and the proxy sends the actual request to the service, returns the response, and adds the required Access-Control-Allow-Origin

response header and other headers to it and passes it on.



So the response with CORS headers enabled is what the browser sees.

https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS has more details on how CORS works, but it's important to know that the browser is the enforcement point of CORS. So in the case of Watson services, the browser will actually receive a response from the Watson API - you can use devtools in the browser to see the response, but the browser will expose the response to your client-side JavaScript code only if the response includes a response header Access-Control-Allow-Origin

to indicate that the server is. the responder decided to receive cross-origin requests from client-side JavaScript running in web applications.

So why, even though all the lines xhr.setRequestHeader("Access-Control-Allow-

in your XHR snippet above just need to be removed, because the headers Access-Control-Allow-*

are the response headers, not the request headers; sending them in a request to the server does not affect CORS because, as noted above, browsers point to the CORS clause, not the server.

So this is not the case when the server receives any request from the browser and says, "OK, I see this request has the correct headers, so I allow it. Instead, the server allows all requests from browsers, just like it does. all requests from non-working tools like your java code or curl or postman or whatever (as long as they are authenticated of course) and sends a response.

The difference is that when a non-browser compatible app receives a response, it doesn't refuse to provide you with the response if it lacks a header Access-Control-Allow-Origin

. But the browser refuses to allow your client-side JavaScript website to access the response if it lacks it.

+5


source


You can also check out some of the Watson SDKs available on GitHub.



+2


source


Some Watson services support CORS, others do not. However, when accessing CORS, you must use Auth Token instead of a combination of username and password *.

This is a partial list of services that support CORS: https://github.com/watson-developer-cloud/node-sdk/tree/master/examples/webpack#important-notes

Here are some examples using the Node.js SDK:

And, a whole host of examples from the Speech JavaScript SDK:

* There are several services that use API keys rather than username / password combinations. In this case, you can use the API key directly from the client code if the service supports CORS.

+2


source


check out this IBM developerWorks tutorial on using Watson Q&A - http://www.ibm.com/developerworks/cloud/library/cl-watson-qaapi-app/index.html#N10229

0


source







All Articles