From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Make a successful REST call from website to LabView web service

I am unable to access a LabView web service from a website because of CORS issues.

I'm working against a LabView web service .exe.  I have a website basically doing a REST GET request to that LabView instance and it fails.

What works:

From a browser, I can hit it directly: 

 

http://localhost:8016/TestService/Add?B=5&A=4

 

and the response is correctly:

 

{"Value":"B=5&A=4","C":9}

 

If I enter the following into the address bar to see if there is a clientaccesspolicy.xml file:

http://127.0.0.1:8016/clientaccesspolicy.xml

I get this response correctly:

 

<?xml version="1.0" encoding="utf-8" ?>
<access-policy>
    <cross-domain-access>
        <policy>
            <allow-from http-request-headers="*" http-methods="*">
                <domain uri="http://*" />
                <domain uri="https://*" />
            </allow-from>
            <grant-to>
                <resource path="/" include-subpaths="true" />
            </grant-to>
        </policy>
        <policy>
            <allow-from http-request-headers="*">
                <domain uri="http://*" />
                <domain uri="https://*" />
            </allow-from>
            <grant-to>
                <resource path="/" include-subpaths="true" />
            </grant-to>
        </policy>
    </cross-domain-access>
</access-policy>

 

What does NOT work:

 

What does not work is when I generate a GET request from within JavaScript on my website.  The error I get back is basically the cross domain denial error message:

Origin http://localhost:55984 not found in Access-Control-Allow-Origin header.
 
I've run Fiddler and used it to force a Response header of "Access-Control-Allow-Origin:*" into the response that LabView returns, and my website is then able to process the message.  It would be fantastic if LabView could return this header, but it does not.

 

It also appears, looking at Fiddler, that LabView returns a response successfully, but the browser is deciding not to read that response because of the missing origin header.  Chrome, IE, Firefox -- all browsers running the website will get the CORS error.
 
How can I get my website to preform a GET request successfully?

0 Kudos
Message 1 of 6
(4,591 Views)

Hi BradRem,

 

In your javascript, did you use a realative path of the url.If you use an absolute path you should put the same "Server" IP address.

Can you post a snapshot of you javascript code to see how do you do the GET request ?

 

Best regards

NI Certified LabVIEW Associate Developer
0 Kudos
Message 2 of 6
(4,571 Views)

I'm using an absolute URL to call the web service.  Currently, I'm testing on my local machine, but when I move this to production, the Origin is going to be reported as the main website so it won't even share the same server IP.  Regardless, the website and the LabView web service are two different domains.

 

Raw Request data

 

GET http://127.0.0.1:8016/TestService/Add?A=1&B=7 HTTP/1.1
Accept: application/json, text/plain, */*
Referer: http://localhost:55984/myprogram/101
Accept-Language: en-US,en;q=0.5
Origin: http://localhost:55984
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko
DNT: 1
Host: 127.0.0.1:8016
Connection: Keep-Alive
Pragma: no-cache

 

Raw Response data

 

(I'm intercepting before it reaches the browser)

 

HTTP/1.1 200 OK
Connection: Keep-Alive
Server: Embedthis-http
Content-Type: application/json; charset=utf-8
Cache-Control: no-cache
Date: Sun, 15 May 2016 12:45:18 GMT
Content-Length: 25
Keep-Alive: timeout=60, max=197

{"Value":"A=1&B=7","C":8}

 

Request is processed, but browser will refuse to read it.

 

Even though the Request is being processed, all browser will refuse to read it because it fails the same-origin policy. For example, the error FireFox (for example) reports is:

 

 

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://127.0.0.1:8016/TestService/Add?A=1&B=1. (Reason: CORS header 'Access-Control-Allow-Origin' missing).

 

 

I'm doing something wrong or LabView is doing something wrong

 

Other tests that I have tried is changing the clientaccesspolicy.xml file to refuse everything, yet my results are the same: the browser refuses to read the response AND LabView still honors the request. After changing the clientaccesspolicy.xml file I've restarted the NI services and I've rebooted.  

 

Also note that if I intercept the Response coming back from LabView and insert the CORS header, the browser will accept the response and life is good.

 

I see that LabView is really pushing itself as an IoT solution and I see that other people are controlling LabView externally, but as I'm trying to control it from a website and I see that it's not returning the headers I expect to see when doing cross-origin requests, I wonder how other people are getting this to work?  Why doesn't LabView return the CORS headers?  Or do I have some fundamental misunderstanding?

0 Kudos
Message 3 of 6
(4,527 Views)

Hi Bradrem,

 

I understand your issue, can you try using the "Set HTTP Header.vi" to add "Access-Control-Allow-Origin'" header to you request response in Labview. You find in attached an example of using this vi. Hope this well help.

 

Best regards

Lahcen

----------------------------------------------------------

NI Certified LabVIEW Associate Developer
0 Kudos
Message 4 of 6
(4,520 Views)

That looks encouraging, but I didn't think that was possible because according to the docs:

 

http://zone.ni.com/reference/en-XX/help/371361K-01/lvconcepts/ws_configuring_headers/

 

....it indicates that you can only set headers for "streaming" because apparently LabView can respond either by streaming or not-streaming(?).  I have a colleague who is responsible for the LabView portion of this project and he told me that since his LabView web service is not doing "streaming", he is unable to set headers.

 

Is that correct or are you able to setup response headers without limitation?

 

 

 

0 Kudos
Message 5 of 6
(4,503 Views)

Apparently LabView WebServices offers at least two "output types": Terminal and Stream.  The collegue I'm working with has the WebService set for Terminal and that does NOT allow you to set Response Headers; only Stream allows you to inject headers. I'm not sure why you can't specify headers regardless of this "output type".

 

Without allowing you to set headers from Terminal output type, I can only see LabView supporting limmited IoT support.

 

Response Header Workaround

 

For my problem, where my website is trying to communicuate with LabView and because modern browsers are looking for the "Access-Control-Allow-Origin" response header that LabView apparently won't send, I've come up with a work-around.

 

I've put together a simple proxy application and instead of my website contacting LabView, it contacts the proxy, then the proxy passes the request onto LabView.  When LabView response to the proxy, the proxy adds the "Access-Control-Allow-Origin" header and returns back to my website caller.

 

So, I had to write a program to simply inject the missing header in the response from LabView.  I wish LabView did this natively, but it doesn't.

Message 6 of 6
(4,434 Views)