HTML5 History.pushState искажает URL-адреса, содержащие процент закодированных символов, отличных от Ascii (Unicode).

В веб-приложении OSS у нас есть код JS, который выполняет некоторое обновление Ajax (использует jQuery, не имеет значения). После обновления страницы выполняется вызов интерфейса истории html5 History.pushStateв следующем коде:

var updateHistory = function(url) {
    var context = { state:1, rand:Math.random() };
    /* -----> bedfore the problem call <------- */
    History.pushState( context, "Questions", url );
    /* -----> after the problem call <------- */
    setTimeout(function (){
        /* HACK: For some weird reson, sometimes something overrides the above pushState so we re-aplly it
                 This might be caused by some other JS plugin.
                 The delay of 10msec allows the other plugin to override the URL.
        */
        History.replaceState( context, "Questions", url );
    }, 10);
};

[ Обратите внимание: полный сегмент кода предоставляется для контекста, часть HACK не является предметом этого вопроса]

Приложение разработано i18n'ed и использует сегменты Unicode с кодировкой URL в URL-адреса, поэтому непосредственно перед отмеченным вызовом проблемыв приведенном выше коде аргумент URL-адреса содержит (как проверено в Firebug):

"/%D8%A7%D9%84%D8%A3%D8%B3%D8%A6%D9%84%D8%A9/scope:all/sort:activity-desc/page:1/"

Закодированный сегмент представляет собой utf-8 в процентном кодировании.URL-адрес в окне браузера: (просто для полноты, не имеет большого значения)

http:///%D8%A7%D9%84%D8%A3%D8%B3%D8%A6%D9%84%D8%A9/

Сразу после вызоваURL-адрес, отображаемый в окне браузера, изменяется на:

http:///%C3%98%C2%A7%C3%99%C2%84%C3%98%C2%A3%C3%98%C2%B3%C3%98%C2%A6%C3%99%C2%84%C3%98%C2%A9/scope:all/sort:activity-desc/page:1/

Закодированный сегмент URL-адреса — это просто моджибаке. , результат использования неправильной кодировки на каком-то уровне. Правильный URL-адрес был бы таким:

http:///%D8%A7%D9%84%D8%A3%D8%B3%D8%A6%D9%84%D8%A9/scope:all/sort:activity-desc/page:1/

Это поведение было проверено как на FF, так и на Chrome.

Интерфейс истории спецификацииничего не говорят о закодированных URL-адресах, но я предполагаю, что стандарт по умолчанию для формирования URL-адресов (кодировка utf-8 и процентное кодирование и т. д.) будет применяться при использовании URL-адресов в вызовах функций для интерфейс.

Есть идеи, что здесь происходит.

Редактировать:

Я не обращал внимания на заглавную букву H в истории — этот код на самом деле использует оболочку History.jsдля интерфейса истории. Я заменил его прямым вызовом history.pushState(обратите внимание на строчную букву h), минуя оболочку, и, насколько я могу судить, код работает, как и ожидалось. Проблема с исходным кодом все еще остается - так что проблема с библиотекой History.js кажется.

12
задан Basel Shishani 17 June 2012 в 06:48
поделиться