Я слышал, что ваша выборка также совместима с IE9.

внешний интерфейс HTTP
Chrome:  You will die!
IE9:     Not today!

задний план

При построении каркаса официального сайта компании используется vuejs, для SEO-оптимизации используется режим маршрутизатора истории, для сетевых запросов используется fetch, а для fetch используется полифилл с whatwg-fetch.Статистика доли рынка браузера Baidu, доля IE9 за весь 2017 год достигла9.50%, а платформа vue также совместима с IE9, поэтому проект должен быть совместим с IE9.

Но полифил выборки не совместим с IE9, в этой статье прослеживается причина проблемы и предлагается решение.

Проблема: доступ запрещен

Откройте страницу в IE9 и обнаружите, что сообщается о запросе на выборку.Unhandled promise rejectionError: 拒绝访问:

  • IE9

    访问拒绝

  • IE11 открывает режим отладки IE9

    访问拒绝

Подозревают проблему совместимости с fetch, проверьте версию:

$npm list whatwg-fetch     
project
└── whatwg-fetch@2.0.3 

Проверьте этосовместимость с whatwg-fetch: поддерживает только до IE10. Затем см.whatwg-fetchv0.11 совместим с IE9, затем понизить:

$ npm uninstall whatwg-fetch
removed 1 package in 4.851s

$ npm install whatwg-fetch@0.11
+ whatwg-fetch@0.11.1
added 1 package in 5.96s

Попробуйте снова,Нашел такую ​​же проблему.

Причина проблемы: IE9XMLHttpRequestКОРС не поддерживается

Полифил выборки реализован с использованием XMLHttpRequest, но в IE9 XMLHttpRequest не поддерживает междоменные запросы.XMLHttpRequestПоддержка междоменных доменов и IE8, IE9 необходимо использоватьXDomainRequestдля достижения междоменного.

затем используйтеXDomainRequestЧтобы реализовать асинхронный запрос, код:

function fetchIe9(url, options = {}) => {
  if (window.XDomainRequest) {
    // https://developer.mozilla.org/en-US/docs/Web/API/XDomainRequest
    // only support GET and POST method
    // request and response content type should be JSON
    // without response status code
    return new Promise((resolve, reject) => {
      const method = options.method || 'GET';
      const timeout = options.timeout || 30000;
      let data = options.body || options.params || {};
      if (data instanceof Object) {
        data = JSON.stringify(data);
      }

      const XDR = new XDomainRequest();
      XDR.open(method, url);
      XDR.timeout = timeout;
      XDR.onload = () => {
        try {
          const json = JSON.parse(XDR.responseText);
          return resolve(json.data);
        } catch (e) {
          reject(e);
        }
        return reject({});
      };
      XDR.ontimeout = () => reject('XDomainRequest timeout');
      XDR.onerror = () => reject('XDomainRequest error');
      XDR.send(data);
    });
  } else {
    // native fetch or polyfill fetch(XMLHttpRequest)
    // fetch...
  }
}

нужно знать, это:

  • XDomainRequestПоддерживаются только методы GET и POST.
  • XDomainRequestНе поддерживает куки
  • XDomainRequestне может быть установленresponseType, обе стороны должны согласовать формат данных
  • XDomainRequestОтвет не имеет кода статуса ответа

Не по теме:whatwg-fetchвсегда используетсяXMLHttpRequestсделать полифилл,whatwg-fetch1.0+IE9 не поддерживается не потому, что он не принятXDomainRequest, но потому чтоКод состояния IE9 не соответствует спецификации выборки, а такжеЦель полифилла — полифиллировать спецификацию, а не обеспечивать совместимость..

Проблема: запрос прерван и зависает

После написания кода, в IE9 сетевой запрос очень странный и часто дает сбой:Запрос длился менее 1 мс, а полученные данные — 0B, без кода состояния.; Но в редких случаях может успешно запрашивать и получать данные.

  • IE9

    异常终止

  • IE11 открывает режим отладки E9 На данный момент режим отладки IE9 IE11 в порядке, похоже, что эмулятор все еще не на месте.

    没有异常终止

После долгих поисков наконец нашел статью:Internet Explorer Aborting AJAX Requests : FIXED

IE timing out the request even though data is being transmitted.

Основная причина, вероятно, в том, что IE9 истечет время ожидания передаваемого запроса.

Решение:

  • Добавить кonprogressОбратный вызов события, сообщает IE9, что этот запрос активен, не истечет время ожидания.
  • Отключите отправку запроса от основного потока, чтобы убедиться, что XDomainRequest был полностью инициализирован.

окончательный код

function fetchIe9(url, options = {}) => {
  if (window.XDomainRequest) {
    // https://developer.mozilla.org/en-US/docs/Web/API/XDomainRequest
    // only support GET and POST method
    // request and response content type should be JSON
    // without response status code
    return new Promise((resolve, reject) => {
      const method = options.method || 'GET';
      const timeout = options.timeout || 30000;
      let data = options.body || options.params || {};
      if (data instanceof Object) {
        data = JSON.stringify(data);
      }

      const XDR = new XDomainRequest();
      XDR.open(method, url);
      XDR.timeout = timeout;
      XDR.onload = () => {
        try {
          const json = JSON.parse(XDR.responseText);
          return resolve(json.data);
        } catch (e) {
          reject(e);
        }
        return reject({});
      };
      // fix random aborting: https://cypressnorth.com/programming/internet-explorer-aborting-ajax-requests-fixed/
      XDR.onprogress = () => {};
      XDR.ontimeout = () => reject('XDomainRequest timeout');
      XDR.onerror = () => reject('XDomainRequest error');
      setTimeout(() => {
        XDR.send(data);
      }, 0);
    });
  } else {
    // native fetch or polyfill fetch(XMLHttpRequest)
    // fetch...
  }
}

В заключение

  • IE9 инициирует междоменный запрос на использованиеXDomainRequest, потому что в IE9XMLHttpRequestМеждоменные вызовы не поддерживаются.
  • XDomainRequestПоддерживаются только методы GET и POST, и нет кода статуса ответа, который можно назватьНесовершенный объект асинхронного запроса HTTP.
  • XDomainRequest не поддерживает указаниеresponseTypeРекомендовать использование запроса и возвращать соглашение о формате данных в виде JSON.
  • whatwg-fetch1.0+IE9 не поддерживается, потому чтоКод состояния IE9 не соответствует спецификации выборки, а такжеЦель полифилла — полифиллировать спецификацию, а не обеспечивать совместимость..

References

  • XDomainRequest

https://developer.mozilla.org/en-US/docs/Web/API/XDomainRequest

  • XMLHttpRequest

https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest

  • XDomainRequest — ограничения, ограничения и обходные пути

https://blogs.msdn.microsoft.com/ieinternals/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds/

  • Internet Explorer Aborting AJAX Requests : FIXED

https://cypressnorth.com/programming/internet-explorer-aborting-ajax-requests-fixed/

EOF