Community Tip - You can Bookmark boards, posts or articles that you'd like to access again easily! X
A user can make a direct REST call to Thingworx platform, but when it comes to a website trying to make a REST call. The platform server blocks the request as it is a Cross-Origin request. To enable this feature, the platform server needs to allow Cross-Origin request from all/specific websites. Enabling Cross-Origin request can be done by adding CORS filter to the server.
CORS (Cross-Origin Resource Sharing) specification enables the cross-origin requests from other websites deployed in a different server. By enabling CORS filter, a 3rd party tool or a website can retrieve the data from Thingworx instance. Follow the below steps inorder to update the CORS filter:
<filter>
<filter-name>CorsFilter</filter-name>
<filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CorsFilter</filter-name>
<url-pattern>/*</url-pattern> // "*" opens platform to all URL patterns, recommended to use limited patterns.
</filter-mapping>
NOTE: the url-pattern - /* opens the Thingworx application to every domain.
<filter>
<filter-name>CorsFilter</filter-name>
<filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
<init-param>
<param-name>cors.allowed.origins</param-name>
<param-value> http://www.customerwebaddress.com </param-value>
</init-param>
<init-param>
<param-name>cors.allowed.methods</param-name>
<param-value>GET,POST,HEAD,OPTIONS,PUT</param-value>
</init-param>
<init-param>
<param-name>cors.allowed.headers</param-name>
<param-value>Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers</param-value>
</init-param>
<init-param>
<param-name>cors.exposed.headers</param-name>
<param-value>Access-Control-Allow-Origin,Access-Control-Allow-Credentials</param-value>
</init-param>
<init-param>
<param-name>cors.support.credentials</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>cors.preflight.maxage</param-name>
<param-value>10</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CorsFilter</filter-name>
<url-pattern>/* </url-pattern> // "*" opens platform to all URL patterns, recommended to use limited patterns.
</filter-mapping>
NOTE: update the cors.allowed.origin parameter with the desired web address
Tested this using an online Javascript editor (jsfiddle) and executing the below script
<script>
var data = null;
var xhr = new XMLHttpRequest();
xhr.open("GET", "http://localhost:8080/Thingworx/Things", true);
xhr.withCredentials = true;
xhr.send();
</script>
The request was successful and list of things are returned.
Hello, I used this approach and I keep getting errors. Problem is that browser sends preflight request 'OPTIONS' and strips appKey header. Which causes 401. Can you please expand this to allow all OPTIONS request without auth?
There might be some issue with TW, response to OPTIONS request from postman is 500 even with correct auth header.
There are three solutions possible:
1) Fix issues in TW core
2) Make tomcat respond 200 to every option request without auth.
3) Add appKey to url as parametr...
For now I use solution number 3, but I would like to learn more about tomcat config.
Thanks in advance!
Jan, I really appreciate your response. We are working on fix to TW core, but in the meanwhile I might suggest appkey to url parameter. Let us know your thoughts.
Thanks,
Giri
Thanks for reply, on second look option one might sound bit rude. Did not meant that, just wanted to point out to some possible issues. Keep up the good work!
I am using Thingworx Version 8 , could you please confirm whether Thingworx Services can be called from Ajax requests by adding the below configuration in tomcats web.xml. I still find that even after adding the CORS filter, the preflight request is being blocked by PTC and hence Thingworx services cannot be called from a browser(XMLHttpRequest or Jquery Ajax request).
<filter>
<filter-name>CorsFilter</filter-name>
<filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
<init-param>
<param-name>cors.allowed.origins</param-name>
<param-value>*</param-value>
</init-param>
<init-param>
<param-name>cors.allowed.methods</param-name>
<param-value>GET,POST,HEAD,OPTIONS,PUT</param-value>
</init-param>
<init-param>
<param-name>cors.allowed.headers</param-name>
<param-value>Content-Type,X-Requested-With,accept,Origin,Access-Control-Allow-Origin,Access-Control-Request-Method,Access-Control-Request-Headers</param-value>
</init-param>
<init-param>
<param-name>cors.exposed.headers</param-name>
<param-value>Access-Control-Allow-Origin,Access-Control-Allow-Credentials</param-value>
</init-param>
<init-param>
<param-name>cors.support.credentials</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>cors.preflight.maxage</param-name>
<param-value>10</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CorsFilter</filter-name>
<url-pattern>/*</url-pattern> // "*" opens platform to all URL patterns, recommended to use limited patterns.
</filter-mapping>
Thanks
Jaya H