I have an issue where CORS is setup in Tomcat correctly. Everything works as expected. We can access resources on the remote host and pull docs from its repository etc. However, we have a bit of code we would prefer to run in an iFrame (document editor) except when we load a new page in this iFrame and use XmlHttpRequest-GET to pull the same document from the same repository the CORS headers are not returned by Tomcat. All client code is on same origin. If we do the very same thing by directly having the iFrame src set to the URL or use Ajax to pull the document it works as expected with no issue. See attached image for clarification.
What are we missing? Disclaimer, I redacted actual urls etc, tried POST and setting content-type "application/x-www-form-urlencoded" and "text/plain" to to see if a preflight request might solve the issue but it did not. Forgive any typos.
Script is in html that is loaded into iFrame from same origin as all client side code e.g. iFrame's src="https://server.com/editor.html".
XmlHttpRequest script in HTML is as follows,
var postget = "GET"
var a = new XMLHttpRequest();
var b = "https://data.server.com/file.txt";
a.open(postget, b, !0,);
if (postget==='POST') a.setRequestHeader( "Content-type", "application/x-www-form-urlencoded" );
a.overrideMimeType && ("binary" !== e ? a.overrideMimeType("text/plain; charset=" + e) : a.overrideMimeType("text/plain; charset=x-user-defined"));
a.onreadystatechange = function () {
var c;
4 === a.readyState && (c = f(b, e, a), l(c.err, c.data));
};
var dummyPayload = (postget==='POST') ? new Uint8Array(1) : null;
try {
a.send(dummyPayload);
} catch (c) {
l(c.message, null);
}
Error is as follows;
Access to XMLHttpRequest at 'https://data.server.com/file.txt' from origin 'https://server.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Using iFrame's src="https://data.server.com/file.txt" works using the document URL just fine.
Tomcat CorsFilter is as follows, https://data.server.com;
<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>https://server.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,charset,Charset,Access-Control-Allow-Origin,Access-Control-Allow-Headers</param-value>
</init-param>
<init-param>
<param-name>cors.exposed.headers</param-name>
<param-value>Access-Control-Allow-Origin,Access-Control-Allow-Credentials,Access-Control-Allow-Headers</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>86400</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CorsFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Here is the request header for the failed attempt using XmlHttpRequest in Iframe html script;
REQUEST HEADER
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Connection: keep-alive
Host: data.server.com
If-Modified-Since: Thu, 21 Jan 2021 19:49:07 GMT
If-None-Match: W/"8938-1611258547000"
Origin: https://server.com
Referer: https://server.com/
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-site
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 11_1_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36
Here is a request header that succeeds with a doc pull using an iFrame with src=url;
REQUEST HEADER
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Authorization: Basic aXJpczp4cmI4ODg=
Connection: keep-alive
Host: data.server.com
Referer: https://server.com/
Sec-Fetch-Dest: iframe
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: same-site
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 11_1_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36
As you all know we are limited by the headers we are allowed to set. The request are different so our question is what in the request is Tomcat not liking? Sec-Fetch-Mode "cors" vs "navigate"?
You will notice there is no Origin in the successful request. We can pull the doc directly from the servlet but passing large data blocks to a iFrame or using a proxy feels unnecessary and sloppy. If the editor was simple and we didn't use it in several different applications then we would just embed it in the core client code but not ideal.
Any help you guys can provide will be greatly appreciated.
This attached image provides all the details regarding config and problem
question from:
https://stackoverflow.com/questions/65876898/tomcat-does-not-send-cors-headers-if-xmlhttprequest-used-from-within-script-in-i