webcompat / web-bugs

A place to report bugs on websites.
https://webcompat.com
Mozilla Public License 2.0
743 stars 66 forks source link

www.koreanair.com - contact us page doesn't load #15690

Closed lhirlimann closed 5 years ago

lhirlimann commented 6 years ago

URL: https://www.koreanair.com/content/koreanair/global/en/customer-support.html#contact-us

Browser / Version: Firefox 60.0 Operating System: Linux Tested Another Browser: Yes

Problem type: Site is not usable Description: Page is blank Steps to Reproduce: 1) go to https://www.koreanair.com/ 2) scroll down and click contact us 3) page never finishes to load and stays blank.

4) Work perfectly in Edge

From webcompat.com with ❤️

softvision-oana-arbuzov commented 6 years ago

Thanks for the report @lhirlimann, following the URL I was able to reproduce the issue. Note: Performing the steps to reproduce, the issue is not reproducible, the page loads.

Console:

ReferenceError: _satellite is not defined[Learn More]
satellite-5a24d47264746d3511006a96.js:1:1
<anonymous>
https://assets.adobedtm.com/42b58b508694b44ac8b88785803d0ae3556c21a8/scripts/satellite-5a24d47264746d3511006a96.js:1:1
_satellite.pushBlockingScript(function(event, target, $variables){
  var px_code_list = koreanair.Cookie.get("px_code_list");
var campaign_code = _satellite.getVar("campaign");

if(campaign_code != undefined && campaign_code != ''){
  campaign_code = campaign_code.toLowerCase();

  if(px_code_list==undefined || px_code_list==''){
    koreanair.Cookie.set('px_code_list', campaign_code+'&');
  }  
  else if(px_code_list.toLowerCase().indexOf(campaign_code) < 0){    
    koreanair.Cookie.set('px_code_list', px_code_list+campaign_code+'&');
  }
  else {}  
}
});

Tested with: Browser / Version: Firefox Nightly 60.0a1 (2018-02-27) Operating System: Linux Ubuntu 16.04

Moving to Needsdiagnosis for further investigation.

karlcow commented 6 years ago

@lhirlimann @softvision-oana-arbuzov it doesn't reproduce for me. Either they changed the site, or either I don't understand how to reproduce it :)

Tell me if it's still happening. Thanks!

softvision-oana-arbuzov commented 6 years ago

@karlcow , I've retested the issue on Windows 10 Pro, and was able to reproduce it by following both the URL and the Steps to Reproduce:. pagenotloading

Tested with: Browser / Version: Firefox Nightly 61.0a1 (2018-04-09)

softvision-oana-arbuzov commented 6 years ago

On Linux, following the URL: https://www.koreanair.com/content/koreanair/global/en/customer-support.html#contact-us, displays the page. Following the Steps to Reproduce:, does not load the page.

karlcow commented 6 years ago

Ah Gotcha. Indeed.

The link in the home page is going to https://www.koreanair.com/global/en/customer-support/contact-us.html

but the page is being redirected to https://www.koreanair.com/content/koreanair/global/en/customer-support.html#contact-us which never finishes loading. It's in a limbo state.

In the console there is a reference error

12:16:35.605 ReferenceError: _satellite is not defined[Learn More] satellite-5a24d47264746d3511006a96.js:formatted:1
    <anonymous> satellite-5a24d47264746d3511006a96.js:formatted:1

The script is https://assets.adobedtm.com/42b58b508694b44ac8b88785803d0ae3556c21a8/scripts/satellite-5a24d47264746d3511006a96.js

_satellite.pushBlockingScript(function (event, target, $variables) {
  var px_code_list = koreanair.Cookie.get('px_code_list');
  var campaign_code = _satellite.getVar('campaign');
  if (campaign_code != undefined && campaign_code != '') {
    campaign_code = campaign_code.toLowerCase();
    if (px_code_list == undefined || px_code_list == '') {
      koreanair.Cookie.set('px_code_list', campaign_code + '&');
    } 
    else if (px_code_list.toLowerCase().indexOf(campaign_code) < 0) {
      koreanair.Cookie.set('px_code_list', px_code_list + campaign_code + '&');
    } 
    else {
    }
  }
});

if I go directly to https://www.koreanair.com/content/koreanair/global/en/customer-support.html#contact-us This is working.

if I have been once to the page and if I click the link, there is no issue.

Probably cookies are already in place.

if I quit and start with a fresh profile, it reproduces.

Screenshot Description

hmm indeed. So the first contact URL has this response.

    <script src="/etc/clientlibs/koreanair/js/vendor/tealeaf_v3_3.js"></script>
    <script type="text/javascript"
        src="/etc/clientlibs/granite/jquery.d311399a202bbfe8f6b94a4546a2a025.js"></script>
    <script type="text/javascript"
        src="/etc/clientlibs/granite/utils.3010ac293e9c3ee5e4d05561c6e817b9.js"></script>
    <script type="text/javascript"
        src="/etc/clientlibs/granite/jquery/granite.b14676fa47cce8b31155c6be3da9e810.js"></script>
    <script type="text/javascript"
        src="/etc/clientlibs/foundation/jquery.d7c42e4a257b8b9fe38d1c53dd20d01a.js"></script>
    <script type="text/javascript"
        src="/etc/clientlibs/foundation/shared.e910b769cd2e558661f961c46223b353.js"></script>
    <script type="text/javascript"
        src="/etc/clientlibs/granite/lodash/modern.7b2eea6898007731c2ec2232f96726c7.js"></script>
    <script type="text/javascript"
        src="/etc/clientlibs/foundation/personalization/kernel.d2952f184e39d06a381cc062de57ed49.js"></script>
    <script type="text/javascript"
        src="/etc/clientlibs/koreanair/libs/head.b69d237a261dcd9d7b55dd3b5bba81af.js"></script>
    <script type="text/javascript">
    window.location.replace(
        "/content/koreanair/global/en/customer-support.html#contact-us"
    );
    </script>
    <script type="text/javascript"
        src="//www.googleadservices.com/pagead/conversion.js"></script>
    <script src="//assets.adobedtm.com/42b58b508694b44ac8b88785803d0ae3556c21a8/satelliteLib-26b1255b2c1d1cac040d84a8779060909b9de8f1.js"></script>
    <script type="text/javascript">
    window.koreanair = window.koreanair || {};
    window.koreanair.HomePage =
        "/content/koreanair/global/en.html";
    window.koreanair.UrlRegion = koreanair.HomePage
        .substr(0, koreanair.HomePage.length - 5)
        .split('/')[3];
    window.koreanair.Navigation = window.koreanair
        .Navigation || {};
    window.koreanair.Navigation.Booking = { "revenue": { "oneway": { "domestic": "/global/en/booking/dow.html", "international": "/global/en/booking/xiow.html" }, "roundtrip": { "domestic": "/global/en/booking/drt.html", "international": "/global/en/booking/xirt.html" }, "multi": "/global/en/booking/mc.html", "schedule": "/global/en/booking/xirt.html" }, "award": { "oneway": { "domestic": "/global/en/booking/adow.html", "international": "/global/en/booking/xaiow.html" }, "roundtrip": { "domestic": "/global/en/booking/adrt.html", "international": "/global/en/booking/xairt.html" }, "multi": "/global/en/booking/xaimt.html" }, "misc": { "payment": "/global/en/booking/on-hold-purchase.html", "reservationSearch": "/global/en/booking/reservation-search.html", "checkIn": "/global/en/booking/check-in.html", "baggage": "/global/en/traveling/baggage-services.html", "carriageConditions": "/global/en/footers/terms-of-carriage.html", "usDOTPage": "/global/en/traveling/baggage-services/not-allowed-to-bring-restricted.html", "paymentPCC": "/global/en/booking/pcc-information/_jcr_content/par/text.html" }, "ruleservice": "/content/koreanair-admin/cross-region/all-languages/flex-pricer-config/_jcr_content/par.bookingrules.json/{bookingType}/from/{origin}/to/{destination}.json", "currencyCCOptions": "/content/koreanair-admin/cross-region/all-languages/credit-card-by-currency/_jcr_content/par/list/{currency}.cardoptions.json/{language}.json", "koreanIssuedCardList": "/content/koreanair-mobile-admin/cross-region/all-languages/korean-issued-credit-cards/_jcr_content/par/list.cardList.json/kr.json", "fleetFinderPage": "/content/koreanair-admin/cross-region/en/fleet-finder-config/_jcr_content/par/urlcodemapper.mapperByCode.json/{aircraftCode}.json", "paymentGuidePage": "/global/en/ticket-information/payment-guide.html", "cardBenefitPage": "/korea/ko/footers/payment-guide/creditcardinstallmentpayment.html", "bankCards": "/content/koreanair-admin/cross-region/all-languages/bank-card-types/_jcr_content/par/list.bankcards.json/{language}.json", "easypayCreditCardOptions": "/content/koreanair-admin/cross-region/all-languages/easy-pay-credit-card-options/_jcr_content/par/list.easypay.json/{language}.json", "mcpcurrencies": "/content/koreanair-admin/cross-region/all-languages/mcp-currencies/_jcr_content/par/list.mcpcurrencies.json/{language}.json", "countries": "/content/koreanair-admin/cross-region/en/country-configuration/_jcr_content/par/list.countries.json", "airlineCodes": "/content/koreanair-admin/cross-region/all-languages/airline-partner-config/_jcr_content/par/airlines.list.json" };
    window.koreanair.pageTitleText = 'Contact Us';

    window.koreanair.Airports = window.koreanair.Airports ||
        {};
    window.koreanair.Airports.airportListUrl =
        '/content/koreanair-admin/cross-region/all-languages/airport-config/_jcr_content/par.listairports.json/{bookingtype}/{direction}/{language}.json';
    window.koreanair.Airports.airportDetailsUrl =
        '';
    window.koreanair.Airports.airportMessagesPage =
        '/content/koreanair-admin/cross-region/en/AirportMessageManagement/_jcr_content/par.message.json/{bookingType}/from/{origin}/to/{destination}.json';

    window.koreanair.ContactKAL = window.koreanair
        .ContactKAL || {};
    window.koreanair.ContactKAL = { "regions": "/content/koreanair-admin/cross-region/all-languages/contact-kal-admin/_jcr_content/par/list.regions.json/{language}.json", "offices": "/content/koreanair-admin/cross-region/all-languages/contact-kal-admin/_jcr_content/par/list.offices.json/{region}/{language}.json", "officePageLocation": "/global/en/customer-support/contact-us/{office}.html" };

    window.koreanair.Alerts = window.koreanair.Alerts ||
        {};
    window.koreanair.Alerts.checkinAlertsUrl = '';

    window.koreanair.Account = window.koreanair.Account ||
        {};
    window.koreanair.Account.accountRecovery =
        '/global/en/profile/account-recovery.html';
    window.koreanair.Account.accountRegistration =
        '/global/en/profile/registration-page.html';
    window.koreanair.Account.profilePage =
        '/global/en/profile/profile.html';
    window.koreanair.Account.familyplaninfo =
        '/global/en/skypass/benefits/family-plan.html';

    window.koreanair.Domestic = window.koreanair.Domestic ||
        {};
    window.koreanair.Domestic.classRules = '';

    window.koreanair.DateFormat = window.koreanair
        .DateFormat || {};
    //      window.koreanair.DateFormat.time = 'HH:mm';
    window.koreanair.DateFormat.time = ('HH:mm').length >
        0 ? 'HH:mm' : 'HH:mm';
    window.koreanair.DateFormat.date = '';
    window.koreanair.DateFormat.daySuffix = '';
    </script>
</head>

<body>

where there is a window.location.replace to the second location failing.

window.koreanair is defined in this first location.

and the second location.

Reading about location.replace()

The Location.replace() method replaces the current resource with the one at the provided URL. The difference from the assign() method is that after using replace() the current page will not be saved in session History, meaning the user won't be able to use the back button to navigate to it.

The page is white but not inactive. It is stucked doing something which eats all the CPU. Around 116% right now.

If I check a performance profile it seems to be due to thousands of setTimeout coming from AppMeasurement

Screenshot Description

  a.Ra = function () {
    a.b = a.d.body;
    a.b ? (a.v = function (c) {
      var b,
      d,
      f,
      e,
      g;
      if (!(a.d && a.d.getElementById('cppXYctnr') || c && c['s_fe_' + a._in])) {
        if (a.Ca) if (a.useForcedLinkTracking) a.b.removeEventListener('click', a.v, !1);
         else {
          a.b.removeEventListener('click', a.v, !0);
          a.Ca = a.useForcedLinkTracking = 0;
          return
        } else a.useForcedLinkTracking = 0;
        a.clickObject = c.srcElement ? c.srcElement : c.target;
        try {
          if (!a.clickObject || a.N && a.N == a.clickObject || !(a.clickObject.tagName || a.clickObject.parentElement || a.clickObject.parentNode)) a.clickObject = 0;
           else {
            var h = a.N = a.clickObject;
            a.la && (clearTimeout(a.la), a.la = 0);
            a.la = setTimeout(function () {
              a.N == h && (a.N = 0)
            }, 10000);
            f = a.Ja();
            a.track();
            if (f < a.Ja() && a.useForcedLinkTracking && c.target) {
              for (e = c.target; e && e != a.b && 'A' != e.tagName.toUpperCase() && 'AREA' != e.tagName.toUpperCase(); ) e = e.parentNode;
              if (e && (g = e.href, a.La(g) || (g = 0), d = e.target, c.target.dispatchEvent && g && (!d || '_self' == d || '_top' == d || '_parent' == d || k.name && d == k.name))) {
                try {
                  b = a.d.createEvent('MouseEvents')
                } catch (l) {
                  b = new k.MouseEvent
                }
                if (b) {
                  try {
                    b.initMouseEvent('click', c.bubbles, c.cancelable, c.view, c.detail, c.screenX, c.screenY, c.clientX, c.clientY, c.ctrlKey, c.altKey, c.shiftKey, c.metaKey, c.button, c.relatedTarget)
                  } catch (m) {
                    b = 0
                  }
                  b && (b['s_fe_' + a._in] = b.s_fe = 1, c.stopPropagation(), c.stopImmediatePropagation && c.stopImmediatePropagation(), c.preventDefault(), a.l = c.target, a.K = b)
                }
              }
            }
          }
        } catch (n) {
          a.clickObject = 0
        }
      }
    }, a.b && a.b.attachEvent ? a.b.attachEvent('onclick', a.v)  : a.b && a.b.addEventListener && (navigator && (0 <= navigator.userAgent.indexOf('WebKit') && a.d.createEvent || 0 <= navigator.userAgent.indexOf('Firefox/2') && k.MouseEvent) && (a.Ca = 1, a.useForcedLinkTracking = 1, a.b.addEventListener('click', a.v, !0)), a.b.addEventListener('click', a.v, !1)))  : setTimeout(a.Ra, 30)
  };
  a.Ra();
karlcow commented 6 years ago

Ah I was able to reproduce once by reloading the page. Which makes me think this is not related to cookies nor navigation, but more a race condition somewhere in the code.

I guess there must be something defining the _satellite object and the timing of that is important because the error doesn't exist when the page is loading.

@wisniewskit What do you think about it?

softvision-oana-arbuzov commented 6 years ago

Re-ping @wisniewskit .

karlcow commented 6 years ago

Was it fixed? @lhirlimann @softvision-oana-arbuzov do you still have the issue?

lhirlimann commented 6 years ago

Nope, still not seeing any content on linux-nightly.

softvision-oana-arbuzov commented 6 years ago

@karlcow , it's blank for me too when performing the "Steps to Reproduce". Following the URL the page loads.

Tested with: Browser / Version: Firefox Nightly 62.0a1 (2018-05-16) Operating System: Linux Ubuntu 16.04

wisniewskit commented 6 years ago

Hmm. This one's very strange, and only intermittently works for me in Firefox. When it works, I can just refresh the page and it eventually breaks, without doing the full STR. But the page seems to load just fine when I have an ad-blocker on:

Loading failed for the <script> with source “https://assets.adobedtm.com/42b58b508694b44ac8b88785803d0ae3556c21a8/satelliteLib-26b1255b2c1d1cac040d84a8779060909b9de8f1.js”. customer-support.html:21:1

Without an ad-blocker, when it breaks I see these clues:

Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user’s experience. For more help http://xhr.spec.whatwg.org/

Navigated to wyciwyg://3/https://www.koreanair.com/content/global/en/customer-support.html#contact-us

Reference Error: _satellite is not defined

Sure enough, when I override that satelliteLib script with an empty file in Tinker Tester Developer Spy, the page otherwise loads fine, so it's that script. Somehow it's causing a wyciwyg:// navigation. I recall those are often caused by sites using document.write incorrectly, and sure enough setting Tinker Tester Developer Spy to ignore document.write also works, and shows me the culprit:

loadScriptSync: function(e) {
  t.write ? E.domReadyFired ? E.notify('Cannot load sync the "' + e + '" script after DOM Ready.', 1) : (e.indexOf('"') > -1 && (e = encodeURI(e)), t.write('<script src="' + e + '"></script>')) : E.notify('Cannot load sync the "' + e + '" script because "document.write" is not available', 1)
},

This is triggered by the Korean Air customer-support.html page, in this script:

<script type="text/javascript">
    var userInfoCall = koreanair.retrieveUserInfo || $.Deferred().resolve({ isAuthenticated:true, language:koreanair.Lang, country:koreanair.Country }).promise();

    userInfoCall.done(function(userInfo) {
        if (window._satellite && _satellite.pageBottom){
                dtmDataLayer.country_korenair = koreanair.Country;
                dtmDataLayer.lang_korenair = koreanair.Lang
                _satellite.pageBottom();
        }
    });
</script>

When things are working, userInfoCall.done is called before the document's readyState changes to interactive. When it's broken, it's because the document is interactive at the time, so the document.write will replace the entire page with a new one containing just the script tag being document.written (which explains why the page goes blank and the script subsequently complains that _satellite is undefined).

Chrome also sometimes calls the functions in the order that causes Firefox to breaks, but it does not do the document.write because DOMContentLoaded has fired in advance, causing E.domReadyFired to be set to true, guarding against the attempt to document.write.

So to sum things up, Chrome always seems to fire the DOMContentLoaded event before userInfoCall.done. Firefox sometimes allows userInfoCall.done to sneak in first, and their script is not designed to handle this case. That is, in Chrome, this always seems to be happening:

  var userInfoCall = koreanair.retrieveUserInfo || ...
** DOMContentLoaded interrupts here, E.domReadyFired set to true in handler **
  userInfoCall.done(function(userInfo) {
    _satellite.pageBottom(); // does not document.write
  });

In Firefox, this sometimes happens instead:

  var userInfoCall = koreanair.retrieveUserInfo || ...
  userInfoCall.done(function(userInfo) {
    _satellite.pageBottom(); // document.writes
  });
** DOMContentLoaded would interrupt here, if document.write had not blanked out the document **

Of course the question is why. At first glance, this would just seem to be site error, as I don't recall there being any guarantee that browsers should always process DOMContentReady before they would call userInfoCall.done.

But then I remembered the last clue, that they're using synchronous XMLHttpRequests. I recall that these can throw off event-ordering, as per bz697151. And when I hacked their scripts to always send XHRs asynchronously, Firefox started to always fire the events in the same "good" order.

I'm not 100% convinced that's the key here, but it does seem to resolve the page-breaking issue.

@miketaylr, @DenSchub, what do you think? It doesn't look like their scripts can be trivially made to work around this. They would either have to drop their use of synchronous XMLHttpRequest, or do something else to guarantee that their retrieveUserInfo promise completes before the document gets to the interactive readyState. I don't think they can just ignore writing the script tag, based on what the script seems to be doing.

miketaylr commented 6 years ago

https://bugzilla.mozilla.org/show_bug.cgi?id=697151#c12 is interesting... this idea of a "polyfix" to hack around this issue.

wisniewskit commented 6 years ago

Agreed, but that specific polyfix has more to do with making sure the site's own async and sync XHRs end up getting events in the right order; I don't think it can fix this kind of thing.

miketaylr commented 6 years ago

@lhirlimann does this work for you now? I can't reproduce the original problem as reported.

lhirlimann commented 6 years ago

https://www.koreanair.com/content/koreanair/global/en/customer-support.html#contact-us is still blank, not visible to me.

karlcow commented 6 years ago

I think there is probably enough information here to go into contact mode.

adamopenweb commented 6 years ago

Reaching out by website contact form: https://www.koreanair.com/content/koreanair/global/en/customer-support.html#cta-large=/global/en/customer-support/contact-us/voice-of-customer.html

adamopenweb commented 5 years ago

Response:

First of all, we apologize for the late reply. We have forwarded your reports to the system department. Thank you again for taking your time to report the issue.

I can't reproduce the issue now in Firefox 65 for MacOS or Windows.

@softvision-oana-arbuzov could you confirm this is fixed please?

softvision-oana-arbuzov commented 5 years ago

@adamopenweb, it is working for me too now, on both scenarios:

Tested with: Browser / Version: Firefox Nightly 65.0a1 (2018-11-15) Operating System: Linux Ubuntu 16.04