In which ChaosTheEternal's IE10 was broken, so he mistakenly asked for help



  • One of the web applications I am working on has a piece in place where this is the expected flow:

    1. User goes to a page where they need to make a selection.

    1. Selection is submitted via AJAX to get return values.
    2. When the AJAX request returns, automatically POST targeting a new window.

    Obviously, that runs into the popup blocker issue, so it was reworked ever so slightly to this:

    1. User goes to a page where they need to make a selection.

    1. Selection is submitted via AJAX to get return values.
    2. In the click event that submitted the AJAX, open a popup window with a specific name to "about:blank".
    3. When the AJAX request returns, perform a POST targeting the popup window's name.

    In Chrome and Firefox, the modified version works, and the POST goes to the popup window. IE, on the other hand, POSTs to the original window and leaves the popup alone.

    I have a very simple demo that can replicate it here:

    <!DOCTYPE html>
    <html>
    <head>
    	<script type='text/javascript'>
    		function OpenPopup() {
    			var wnd = window.open("about:blank", "Popup", "");
    			return !!wnd;
    		}
    	</script>
    </head>
    <body>
    	<form target="Popup" method="GET" action="https://www.google.com/">
    		<input type="button" value="Open Popup" onclick="return OpenPopup();" />
    		<input type="submit" value="Submit Form" />
    	</form>
    </body>
    </html>
    

    Testing in IE, if you click Submit Form first, it POSTs to Google in a new tab or window (as expected, since the named target doesn't exist), but if you click Open Popup to get the "popup" then click Submit Form, it POSTs that page to Google instead of the "popup" that should be the named target.

    I'm just scratching my head and not finding anything as to why this happens in IE.


    Disregard, issue was with IE10 on my workstation specifically, issue did not exist on other workstations on various versions of IE, including other IE10s.



  • IE apparently doesn't set the name attribute, so it's not being effectively targeted.

    http://terminalapp.net/submitting-a-form-with-target-set-to-a-script-generated-iframe-on-ie/



  • Is there a reason the code has to work this way?

    The obvious solution would be to do the POST via Ajax and divorce it completely from the pop-up window code. That'll also make it easier to get rid of the pop-up in the future, which you should do.



  • @rad131304 said:

    IE apparently doesn't set the name attribute, so it's not being effectively targeted.

    Good to know, though sadly, the workaround won't work for me, because I'm not posting to an <iframe>.


    @blakeyrat said:

    Is there a reason the code has to work this way?

    Mandated from the top. Concept is, user clicks button for the external site, we open the new window to the external site with details based on their selection, user does their business, closes that window, and they "come back" to our site.

    That is how the original version of our site basically did it, except it is being blocked by popup blockers, since it tries to submit a form to a new window on page load and doesn't use AJAX anywhere.

    @blakeyrat said:

    do the POST via Ajax

    The POST to the external site is a post to a web page, not a web service.


  • :belt_onion:

    Everything I said before was dumb because I didn't read the problem carefully enough.

    Also... your demo works for me in IE11 ;)



  • @darkmatter said:

    I believe you have to save the wnd object for IE to reference that popup again later.

    In the actual code where I'm testing this, I did try having the wnd object stored on the page's scope to no avail.

    @darkmatter said:

    your demo works for me in IE11 :wink:

    Wonderful, that means it's only broken in IE9 and IE10.



  • @ChaosTheEternal said:

    Mandated from the top. Concept is, user clicks button for the external site, we open the new window to the external site with details based on their selection, user does their business, closes that window, and they "come back" to our site.

    That is how the original version of our site basically did it, except it is being blocked by popup blockers, since it tries to submit a form to a new window on page load and doesn't use AJAX anywhere.

    Ok; the other domain rules out AJAX (unless you dig into CORS), but you can still do what you need with an iframe.

    @ChaosTheEternal said:

    The POST to the external site is a post to a web page, not a web service.

    That doesn't really matter. XMLHttpRequest doesn't care where the request goes or why.


  • :belt_onion:

    @ChaosTheEternal said:

    Wonderful, that means it's only broken in IE9 and IE10.

    It works in IE11 doing IE7, IE9, IE10 emulation too.

    Have you re-opened your browser lately? Does the base window that you're starting from at this point happen to be named Popup? :trolleybus:



  • @blakeyrat said:

    but you can still do what you need with an iframe

    How? Nothing in my head sees how I can change from "posting to new window" to "posting to iframe which then becomes a new window".

    @blakeyrat said:

    XMLHttpRequest doesn't care where the request goes or why

    The question is, how do I handle the response, which is a web page. Also note, any AJAX I'm doing right now is through jQuery, I haven't been doing any straight XMLHttpRequests yet (nor have I ever).


    I know, :trolleybus: and all, but

    @darkmatter said:

    Have you re-opened your browser lately?

    Yes, changing the name or restarting IE10 fresh, still doesn't work.


  • sockdevs

    @ChaosTheEternal said:

    The question is, how do I handle the response, which is a web page.

    Set it as the source of the iframe?
    @ChaosTheEternal said:
    Also note, any AJAX I'm doing right now is through jQuery, I haven't been doing any straight XMLHttpRequests yet (nor have I ever).

    Doesn't matter; you can still get the full response data. Doesn't have to be JSON; can be anything.



  • @darkmatter said:

    It works in IE11 doing IE7, IE9, IE10 emulation too

    This works for me as well in IE9 and IE10.


  • :belt_onion:

    @RaceProUK said:

    Set it as the source of the iframe?

    If it's always a GET, this would work, or you can do the routing in the window.open() command and move that to your onsubmit to create the popup, rather than making the popup at one point and then later telling it where to go as the target of the post.



  • @RaceProUK said:

    Set it as the source of the iframe?

    You mean put the url of the response to the src in the <iframe>? Effectively making them load it twice?

    Also, again, needs to be in a popup, not in an <iframe>.


  • :belt_onion:

    @ChaosTheEternal said:

    Yes, changing the name or restarting IE10 fresh, still doesn't work.

    One other note is that if you have protected mode enabled (like if you were testing this on the win2k13 webserver itself, assuming it's a winserver, those browsers are usually set up with protected mode on), I think IE won't let you do shit with popups.


  • :belt_onion:

    @ChaosTheEternal said:

    You mean put the url of the response to the src in the <iframe>? Effectively making them load it twice?

    Also, again, needs to be in a popup, not in an <iframe>.

    <!DOCTYPE html>
    <html>
    <head>
    	<script type='text/javascript'>
    		function OpenPopup() {
    			var where2go = functionThatReadsFormDataAndMakesAUrl();
    			var wnd = window.open(where2go, "Popup", "");
    			return !!wnd;
    		}
    	</script>
    </head>
    <body>
    	<form onsubmit="OpenPopup()" method="GET" action="https://www.google.com/">		
    		<input type="submit" value="Submit Form" />
    	</form>
    </body>
    </html>
    

    Should work, just missing the implementation for the functionThatReadsFormDataAndMakesAUrl


  • sockdevs

    @ChaosTheEternal said:

    @RaceProUK said:
    Set it as the source of the iframe?

    You mean put the url of the response to the src in the <iframe>? Effectively making them load it twice?

    No, the content of the response; you have access to it.
    @ChaosTheEternal said:
    Also, again, needs to be in a popup, not in an <iframe>.

    Still applies



  • @darkmatter said:

    One other note is that if you have protected mode enabled (like if you were testing this on the win2k13 webserver itself, assuming it's a winserver, those browsers are usually set up with protected mode on), I think IE won't let you do shit with popups.

    My IE9 and IE10 both have protected mode on. Could it be a security setting or zone issue?


  • :belt_onion:

    really? maybe it's cool with it if you're running the sample page from localhost or off the file system, which would make IE set it to be in the trusted zone.

    Or maybe IE's protected mode is as useless as a condom on a porcupine. I don't really know, I only read that it wouldn't work with popups in protected mode and i've never bothered to try myself because there's no reason for me to do that.



  • Years ago I had a similar problem (with bypassing popup blockers). I've been trying to find a coding example, But I CBA to fire up my old Server to look further.

    Anyway my solution was (roughly). Return the data to the original window and get the original window to create a new window object and write the data into it. Then focus on that window.

    Caveat: "my" data was a complete HTML Page, and the IE Versions I had the issues with was 6/7, maybe 8 - or at least 8 was new then



  • @darkmatter said:

    if you're running the sample page from localhost or off the file system

    I am doing neither.

    I am thinking there is something else going on here that is causing this not to work for @ChaosTheEternal



  • @RaceProUK said:

    the response

    XMLHttpRequest cannot load https://third.party.site/page. No 'Access-Control-Allow-Origin' header is present on the requested resource.

    That's probably going to be the whole "delving into CORS" thing, right?


    @jaming said:

    something else going on here that is causing this not to work for @ChaosTheEternal

    If there is, it'd be nice to find out. I haven't touched any IE settings for IE10 on my workstation beyond having localhost bypass the popup blocker, which I took off today to test this.

    I did verify IE11 didn't have the issue by having the sample page published to my IIS and my boss testing it (as he has IE11 while I have IE10).


  • sockdevs

    @ChaosTheEternal said:

    That's probably going to be the whole "delving into CORS" thing, right?

    Looks like it



  • @ChaosTheEternal said:

    How? Nothing in my head sees how I can change from "posting to new window" to "posting to iframe which then becomes a new window".

    Well you can, but that wasn't really my point.

    My point was to gently suggest to you that every website on Earth should have gotten rid of their pop-up windows about 7 years ago, and so whatever solution you pick should be one that enables you to get rid of the pop-up window. An iframe for example.

    @ChaosTheEternal said:

    The question is, how do I handle the response, which is a web page.

    Do whatever? Feed it into the pop-up window via. DOM. Or feed it into an iFrame via DOM. Or just cram it in a DIV. It's HTML, you can do whatever with it.

    The problem you have is you won't be able to POST to the third-party site unless they have CORS set up or they happen to be on the same domain as you.

    @RaceProUK said:

    No, the content of the response; you have access to it.

    Sigh. You're leading him down a blind alley, XSS protection is going to prevent this from working.

    @ChaosTheEternal said:

    That's probably going to be the whole "delving into CORS" thing, right?

    See? Jeez I go to grab lunch and look what happens.


  • sockdevs

    @blakeyrat said:

    @RaceProUK said:
    No, the content of the response; you have access to it.

    Sigh. You're leading him down a blind alley, XSS protection is going to prevent this from working.

    Oh, how could I be so stupid? If only there was a way around that! Something like this maybe:
    Oh well, since it doesn't exist and there are no real-world implementations or international standards, guess we'll have to forget the whole thing.



  • Dude.

    He's dealing with a website that, in 2015, OPENS A POP-UP WINDOW.

    Do you really think we're dealing with the kind of development environment that's going to have CORS set up with their business partner? They probably haven't even touched any of this code since before CORS existed.

    There is no universe in which "people who are comfortable with CORS" and "people who think pop-up windows on a website are acceptable" intersect.


  • sockdevs

    @blakeyrat said:

    There is no universe in which "people who are comfortable with CORS" and "people who think pop-up windows on a website are acceptable" intersect.

    Am I to take from that that you have visited every website in every universe? Or shall I go with the more plausible 'you're talking out your arse' again?



  • Guys this is Coding Help--knock it off.


  • Discourse touched me in a no-no place

    @blakeyrat said:

    unless you dig into CORS

    Is CORS much of a problem if you lock it down with url/host/etc rules, and you have control of both servers? It would've saved me a shitload of work in a recent project, but the guy running the servers had a shitfit and flat-out ruled it out.



  • @FrostCat said:

    Is CORS much of a problem if you lock it down with url/host/etc rules, and you have control of both servers?

    Depends on what you mean by "much of a problem." Since it sounds like he needs IE9 support, it might be ruled-out by that alone... but (in general) CORS works fine, and does what you expect, and AFAICT is secure.


  • Discourse touched me in a no-no place

    @blakeyrat said:

    Depends on what you mean by "much of a problem."

    Well, if you're explaining CORS to someone and suggesting it as the solution to a problem, and the guy running the webserver immediately freaks out about that opening up the possibility of getting hacked etc., on the spectrum of "that's an entirely reasonable worry" and "he's being needlessly hysterical", where, rougly, does his response fall?

    IOW how reasonable is it to use CORS if you apply some precautions like enabling remote-server whitelisting and you control both servers?



  • @FrostCat said:

    IOW how reasonable is it to use CORS if you apply some precautions like enabling remote-server whitelisting and you control both servers?

    I'm not a security expert. As far as I'm concerned, the biggest weakness is that it means you have to completely trust your partner site.

    If (hypothetical) you personally control both servers, before diving into CORS, I'd simply put both of them on the same domain. It's a much simpler solution and minimizes XSS risk factors.



  • @jaming said:

    I am thinking there is something else going on here that is causing this not to work for @ChaosTheEternal

    This appears to be the case. Testing on my IE10 with the page being served by my local IIS, it jacks up like I'd mentioned in the OP. Testing the actual site logic via VS2010's dev server on IE10, same result.

    Testing every version of IE from 8 to 11 from different machines, but still looking at my IIS version of the test page, it worked. Problem exists in my IE somewhere, which is funny, because I haven't messed with any of IE's settings beyond turning off popup blocking for "localhost" and my computer name and also telling IE to not go into Compatibility Mode when on the Intranet.


  • Discourse touched me in a no-no place

    @blakeyrat said:

    If (hypothetical) you personally control both servers, before diving into CORS, I'd simply put both of them on the same domain. It's a much simpler solution and minimizes XSS risk factors.

    Hmm. We looked at doing that but--and maybe it was just I didn't spend enough time, because Captain Security Freakout was busy running in circles screaming and shouting--couldn't figure out how to do that correctly. We had one Windows machine running IIS and another running Tomcat; the latter was using its preferred ports, which seemed to preclude being on the same domain. We thought about moving Tomcat to use 80/443, but other issues would've made that problematic, so we eventually went a slightly more convoluted route that avoided AJAX entirely, but I'm just wondering, for future reference, if we could've gotten same-domain to work.



  • @ChaosTheEternal said:

    If there is, it'd be nice to find out. I haven't touched any IE settings for IE10 on my workstation beyond having localhost bypass the popup blocker, which I took off today to test this.

    I will have to play with this some more when I have a chance. Right now I am super busy. Do you work somewhere that would have a group policy that could be changing IE settings?



  • Question: How complicated is the page the user receives after POST to the other server? Also, is it interactive? As in, should user be able to click links and do stuff inside this popup?



  • It takes a bit of work to setup, but I like to use the vms from here to test.



  • @jaming said:

    Do you work somewhere that would have a group policy that could be changing IE settings?

    Possibly, but there's only 5 of us, we aren't "mandated" to use IE, and we all have local admin, so I wouldn't think there'd be any IE specific Group Policy settings.

    There are some Group Policy settings coming down, though, as I can't save credentials to half of the servers I RDP to (while my boss can and does).



  • @ChaosTheEternal said:

    Mandated from the top. Concept is, user clicks button for the external site, we open the new window to the external site with details based on their selection, user does their business, closes that window, and they "come back" to our site.

    If you cannot post a form directly to a different window, why not clone the entire form into the different window and post the clone without using the target attribute on the form at all? E.g.

    function onFormSubmit( event ) {
      var
        form  = event.target,
        popup,
        doc,
        domain;
    
      event.preventDefault();
    
      // The document object associated with a javascript: protocol URL should be synchronously
      // available, but not yet finished loading. This is what we are looking for.
      popup = window.open( "javascript:false" ); 
      try { 
        // However, *accessing* the document may fail when the main document's domain is set.
        // Merely accessing the domain property may cause its value to be set to a value, so
        // we have to try blindly and cannot inspect the domain property to make an informed
        // decision here.
        doc = popup.document; 
      } catch( err ) {
        // Instead, we load another javascript: protocol URL that updates the popup document's
        // domain to match the main document domain.
        domain = document.domain;
        popup.location.href="javascript:var d=document.open();d.domain='"+domain+"';void(0);";
        doc = popup.document;
      }
    
      // Open the popup document for writing now that we have an accessible reference
      // that won't raise security errors.
      doc = doc.open();
      doc._load = function() {
        // Don't forget to again make the domains match again before doing anything else.
        if ( domain ) this.domain = domain;
    
        // Create and append a fresh form element; run a left-to-be-defined function
        // to clone the main form's fields to this clone in the popup; and submit the
        // populated clone.
        var clone = this.body.appendChild(this.createElement("form"));
        cloneFormFields( form, clone );
        clone.submit();
      }
      
      // Write out a document body that will call the form processing logic we just
      // defined, after the document finishes loading.
      doc.write( "<body onload='document._load();'>");
      doc.close();
    
      // Finally: Bitch some more about IE making this necessary...
    }
    


  • Similar to @ragnax

    index.html
    <!DOCTYPE html>
    <html>
    <head>
    	<title></title>
    </head>
    <body>
    	<form id="form">
    		<input type="button" value="Submit" onclick="return submitPopup();" />
    	</form>
    
    	<script type="text/javascript">
    		function getAjaxParams(cb) {
    			setTimeout(function () {
    				cb(null, {
    					param1: "A",
    					param2: "B"
    				});
    			}, 100);
    		}
    
    		function submitPopup() {
    			var wnd = window.open("popup.html", "Popup", "");
    			getAjaxParams(function (err, data) {
    				// Fill in the form in the popup
    				var targetForm = wnd.document.forms[0];
    				targetForm.param1.value = data.param1;
    				targetForm.param2.value = data.param2;
    
    				// Submit
    				targetForm.submit();
    			});
    		}
    	</script>
    </body>
    </html>
    
    popup.html
    <!DOCTYPE html>
    <html>
    <head>
    	<title></title>
    </head>
    <body>
    	<form method="POST" action="https://www.url-to-the-outside-service/">
    		<input type="hidden" name="param1" />
    		<input type="hidden" name="param2" />
    	</form>
    	<div></div>
    </body>
    </html>
    

    My IE is broken ATM, so I can't test it there.


Log in to reply
 

Looks like your connection to What the Daily WTF? was lost, please wait while we try to reconnect.