I'm currently looking into custom visualisations in Qlik Sense and Qlik View, trying to get a grasp on the capabilities and limitations. One interesting area is loading data from external web API's. I'm aware that Qlik load scripts can do this as a part of normal data loading, and that such data is available to extensions, which is great, but not what I'm looking for right here. I want a way to load data live and on demand.
So, coming from a web developer background, the first thing I tried was using jQuerys AJAX methods. This fails for normal web API's, but works for API's that allow cross-origin requests, so I'm guessing the restriction is the same as with any web page trying to access data from another domain with client-side code. I've verified an API that uses JSONP to accomplish cross-origin capabilities, and I'm guessing that it would work with CORS as well, although I haven't verified that yet.
This makes sense, but what I would really like to see is a method in the Qlik JS API's that would trigger a request from the native environment (bypassing cross-origin restrictions) and then return the data to the JS environment asynchronously.
I've been reading documentations, but can't seem to find anything like that. I'm interested in this for both Qlik View and Qlik Sense. Am I missing something, or is this not supported or even discouraged? Is there an alternative approach besides the ones I've mentioned above?
Too bad there isn't a function like that. I think it would be quite useful, since the majority of API's out there don't allow direct cross-origin access.
Before I mark your reply as the correct answer, I feel I must object to your claim that it wouldn't matter - servers or desktop applications normally don't enforce any same-origin-policy like browsers do. If Qlik's desktop or server application did that, they wouldn't be able to use external web API's as data sources in normal load scripts either, and they certainly are able to do that. Right? Or maybe I just misunderstood your comment.
Well what a browser can't do is to "fake" it's origin if that's what you mean. But a normal API would implement some kind of re-write on their end to accept different http origins.
I admit that CORS used to be a more important issue but with modern browsers, and the ones Sense supports, that implement html5 it's a lot less of an issue these days. The XMLHttpRequest supports all kinds of cors requests these days.
But if you can provide a good use-case then sure, we can put it into consideration! Opening up your server to external http traffic feels scary though...
In the end, I went with another weather API - Yahoo Weather, which supports CORS, but has less data with less precision for my use case. I shouldn't talk about what's more common because I don't know, but I'm sure there are plenty of potentially useful API's out there that still do not support CORS.
What people normally do when they want to use an API like that as part of a web application is that they let the web server do the request instead, acting like a proxy and passing the result back to the client. The web server has no problem with making a request to any public URL.
My though here is that the QV/QS desktop or server application could do the same thing, since it has the same role as a web server to some extent. After all, QV/QS can make requests to API's like that when executing the load script. So that's the idea that you could take into consideration, if you want.
And, just for arguments sake, I'm not quite sure how web servers and other applications like curl and such do it, but my understanding is that it is the browser that enforces the CORS policy, adds the special request headers and respects the response headers. It only does this on AJAX requests, not in requests for resources like images or scripts, so it definitely COULD do it. I know that in Chrome, you can even bypass this behaviour with special startup flags, which will then allow the client to do any cross-domain requests it wants. This is off course not a way to solve any problem here, but just to illustrate.