Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
173 views
in Technique[技术] by (71.8m points)

javascript - Tomcat does not send CORS headers if XmlHttpRequest used from within Script in iFrame

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
Waitting for answers

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...