Support Questions

Find answers, ask questions, and share your expertise
Announcements
Celebrating as our community reaches 100,000 members! Thank you!

How can I enable CORS in Jetty so I can access Nifi REST API

avatar
Explorer

Hi all,

 

I want to access Nifi REST API from a different client machine which is in a different domain. The REST API is up and running but gives me a CORS error when I try accessing the API from a client in a different domain. Please see below -

Access to XMLHttpRequest at '...' from origin 'null' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

 

I understand that I need to change Jetty's web.xml to allow cross origin requests. I can't seem to find web.xml in my nifi install. This is a nifi docker container.

Any help I can get in this is much appreciated. Please also let me know if there's a better solution than changing web.xml. I tried CORS browser plugins but haven't been able to get them to work.

 

Thanks in advance.

1 ACCEPTED SOLUTION

avatar
Super Guru

@RB764 ,

 

Ok, I see. In the case of running JS code on the browser client, it makes sense to see the errors that you are seeing. That's exactly what CORS restrictions are designed for.

 

Are you loading this script from a file locally on your computer or is this part from a web application that you have running on a server?

 

If this is local to your computer, I would recommend that you use some other language to interact with NiFi, since running this locally on a browser has limitations. In Python, for example, you can use the nipyapi module, which makes it really easy to interact with the NiFi API:

 

from nipyapi import config, security
from nipyapi.nifi.apis.flow_api import FlowApi

config.nifi_config.host = 'https://<<server host:port>>/nifi-api'
security.set_service_ssl_context(service='nifi', ca_file='<</path/to/truststore.pem>>')
security.service_login(service='nifi', username='<<user>>', password='<<pwd>>')

api = FlowApi()
summary = api.get_cluster_summary()

 

If what you are trying to do is part of a web application, the interaction between application and NiFi should happen on the server side instead of the browser. This would also eliminate any sort of CORS issues.

 

Cheers,

André

 

--
Was your question answered? Please take some time to click on "Accept as Solution" below this post.
If you find a reply useful, say thanks by clicking on the thumbs up button.

View solution in original post

5 REPLIES 5

avatar
Super Guru

@RB764 ,

 

What are you using to access the NiFi REST API. Could you give us an example of what your API call looks like?

It's possible to access the API from a client in a different domain without any reconfiguration.

 

Cheers,

André

--
Was your question answered? Please take some time to click on "Accept as Solution" below this post.
If you find a reply useful, say thanks by clicking on the thumbs up button.

avatar
Explorer

Thanks for the prompt response @araujo 

 

I am trying to call /nifi-api/flow/cluster/summary from Javascript using XMLHttpRequest. The intent is to be able to display output from the query in the page.

 

My code is as below:

<script>
    // javascript, jquery calls for calling APIs
    let xhrPostNifi = new XMLHttpRequest();
    xhrPostNifi.withCredentials = true;
    xhrPostNifi.open("GET", "https://<<server url>>/nifi-api/flow/cluster/summary");
    xhrPostNifi.setRequestHeader("Authorization", "Basic xxxxxxxxxxxxxxxxx");
    xhrPostNifi.setRequestHeader('Authorization', 'Bearer <<bearer token>>');
    xhrPostNifi.setRequestHeader(
                       "Content-type",
                       "application/json;charset=UTF-8"
                   );
        xhrPostNifi.onreadystatechange = function () {
        if (this.readyState == 2) {
            console.log("Recieved response - nifi");
        }
        if (this.readyState == 4 && this.status == 200) {
            // Process recieved data
            strJSONBuffer = this.responseText;
            console.log(strJSONBuffer);

            //populateFilterData();
            console.debug("Response received.... "+strJSONBuffer);
        }
    };
    xhrPostNifi.send();
  </script>

avatar
Explorer

and this is the error I get when I call using XMLHttpRequest -

Access to XMLHttpRequest at '.../nifi-api/flow/cluster/summary' from origin 'null' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

avatar
Super Guru

@RB764 ,

 

Ok, I see. In the case of running JS code on the browser client, it makes sense to see the errors that you are seeing. That's exactly what CORS restrictions are designed for.

 

Are you loading this script from a file locally on your computer or is this part from a web application that you have running on a server?

 

If this is local to your computer, I would recommend that you use some other language to interact with NiFi, since running this locally on a browser has limitations. In Python, for example, you can use the nipyapi module, which makes it really easy to interact with the NiFi API:

 

from nipyapi import config, security
from nipyapi.nifi.apis.flow_api import FlowApi

config.nifi_config.host = 'https://<<server host:port>>/nifi-api'
security.set_service_ssl_context(service='nifi', ca_file='<</path/to/truststore.pem>>')
security.service_login(service='nifi', username='<<user>>', password='<<pwd>>')

api = FlowApi()
summary = api.get_cluster_summary()

 

If what you are trying to do is part of a web application, the interaction between application and NiFi should happen on the server side instead of the browser. This would also eliminate any sort of CORS issues.

 

Cheers,

André

 

--
Was your question answered? Please take some time to click on "Accept as Solution" below this post.
If you find a reply useful, say thanks by clicking on the thumbs up button.

avatar
Explorer

Thanks @araujo I am using server side calls to get the information and then pass it on through to the client side. With this approach, all API calls are made from the server side component.