Incomplete XHR responses from IIS with compression
Asked Answered
C

1

6

I'm loading scripts with jQuery ajax.

Here's a snip from the loader code, for what it's worth.

var resources = ['knockout-3.2.0.js', 'fonts/fontawesome-webfont.eot', ... ];
var retryCount = 0;
load(0);
function load(i) {
  if (i == resources.length) {
    $("#progBar").width("100%");
    $("#progCaption").text("executing App/main...")
    var requireScript = document.createElement('script');
    requireScript.setAttribute("type", "text/javascript");
    requireScript.setAttribute("src", "Scripts/require.js");
    requireScript.setAttribute("data-main", "App/main");
    head[0].appendChild(requireScript);
  }
  else {
    $("#progBar").width(100 * i / resources.length + "%");
    var r = resources[i];
    switch (r.substring(r.lastIndexOf('.'))) {
      case ".js":
        $("#progCaption").text(r);
        $.getScript('Scripts/' + r)
        .done(function (data) {
          retryCount = 0;
          load(++i);
        })
        .error(function (err) {
          if (err.status == 404 || retryCount == 3) {
            load(++i);
          } else {
            retryCount++;
            console.log('Retry ' + r);
            load(i);
          }
        });
        break;
      ...

Recommended syntax for getScript only takes one parameter. Either it's a valid URL or not. Because the start of the resource is returned we know the URL is valid . There is no error in the invoking code, jQuery is failing to get the entire response before parsing it as a script.

Pointed at the same public facing server, $.getScript() throws an error even though err.status reports 200 OK. Inspection of the data shows that it is truncated, and the error is probably a JS parse failure as a result of the truncation.

This only happens with IE11 at work, and the problem stops manifesting when the traffic is routed through Fiddler. It doesn't occur at all on IE11 at home. Changing 'knockout-3.2.0.js', to 'knockout-3.2.0.debug.js', causes knockout to load without a hitch, however bootstrap.js isn't minified and it does play up, so it's not as simple as no line breaks. I thought it might be some kind of server caching issue fixed by the name change (it can't be a browser caching problem since getScript applies a cache-buster parameter) but I tried renaming knockout-3.2.0.js to knockout-3.2.0.min.js and it made no difference.

Questions with similar symptoms:


I verified that IE at home and at work were both 11.0.9600.17690 update KB3032359.

The problem vanished when I disabled IIS compression.

I don't know whether it was static or dynamic compression because I turned them off at the same time.

If anyone from Microsoft wishes to investigate (I wouldn't be surprised if the answer is no, it's a bit of an edge case)... I have PCAP files of the failing exchange between client and server.

Diagnostic summary

  • it's not the network, it fails with an alternate route through my phone
  • it's not the version of IE, same IE build at home does not fail
  • it's not the platform (both on Win81) although it could be network hardware drivers
  • it's not IIS, works at home and on my WinPhone81 and for all other browsers
  • it is IIS, turning off server compression fixes it
  • it's not IIS, compression worked fine for other browsers, although I didn't think to capture the traffic with a browser that worked with compression on
  • interposing Fiddler resolved the problem while compression was active
  • it's not a browser caching problem, getScript supplies a cache-buster parameter and when I deliberately allowed caching it was obvious in the capture files as http no-change responses.

I have the oddest feeling this is related Why does IE11 create blank post request except when Fiddler is running? but I couldn't say why.

Once the files are in cache their size ceases to signify, which why I run a pre-loader - for a SPA like mine it's effectively installation. A powerful argument for SPA over traditional application architectures. But lengthy setup does somewhat mar the first time experience.

Centaury answered 8/4, 2015 at 3:19 Comment(6)
It happens in a particular script or with all scripts?Magruder
It happens with large, minified scripts. In particular, bootstrap.js and knockout-3.2.0.js - interestingly, knockout-3.2.0.debug,js is larger and is processed without any problem.Centaury
Another one for the stack of #IEProblems lolTemporize
Perhaps you should put it in the jQuery bugs instead? All three browsers have problems. IE issues are historically high profile as a result of historically high market share. Frankly I have more trouble with Firefox.Centaury
Did you dig into this more, I've run into the same issue serving jQuery and jQuery UI using Asp.NET, MVC, and IIS 8.5. Turning off dynamic content compression solves it for me but I'm still looking for the root cause of why dynamic content compression causes IIS to barf when serving those two files in particular.Gca
@JoshR - No. As you can see from Eric Law's comment on my answer, it was escalated. I have had no further contact either from Eric or from anyone at Microsoft.Centaury
C
0

The problem is resolved by disabling compression in IIS.

Centaury answered 9/4, 2015 at 5:19 Comment(1)
Obviously, that's a unpleasant workaround. If you can share the PCAPs with me (use Help > Send Feedback in Fiddler) I can get them to the right folks inside MSFT.Munition

© 2022 - 2024 — McMap. All rights reserved.