HTML5 pushState с маршрутизатором Backbone.js не работает на определенном сервере, но работает на других

Рвал на себе волосы по одной проблеме. Кажется, я не могу понять, почему мой маршрутизатор pushState не работает на нашем сервере разработки, в то время как он отлично работает на двух других реальных серверах (промежуточный и рабочий домен клиента), а также работает на моем локальном сервере MAMP.

Вот мой роутер:

    jQuery(function(){
        // define routes
        var Router = Backbone.Router.extend({
           routes: {
                '': 'chrono',
                ':number': 'chrono',
                ':number/plus': 'chrono'
           },

          // load views
          initialize: function() {
              Backbone.history.start({
                  pushState: true,
                  hashChange: false     // use html5 pushState with hashChange set to false
                                        // to handle navigation of hash anchors
            });
          },

          chrono: function(number) {
                url = window.location.hash.split("/");

                this.reset();
                this.content = new chronoView();

                if(number == undefined){
                    number = 0;
                }
                if(url[1]=="plus") {
                    this.content.showMiddleBox();
                    jQuery('#overlay2').show();
                }
          },

          reset: function() {
                if (this.content != undefined){
                    this.content.hide();
                 }
          }
      });

      var Router = new Router;
    });

В моем файле .htaccess на нерабочем сервере уже есть довольно много правил перезаписи движка, а сам файл состоит из 200+ строк, но вот то, что я считаю важными частями:

    # Block access to "hidden" directories whose names begin with a period. This
    # includes directories used by version control systems such as Subversion or Git.
    <IfModule mod_rewrite.c>
      RewriteCond %{SCRIPT_FILENAME} -d
      RewriteCond %{SCRIPT_FILENAME} -f
      RewriteRule "(^|/)\." - [F]
    </IfModule>

    <IfModule !mod_rewrite.c>
        # If we don't have mod_rewrite installed, all 404's
        # can be sent to index.php, and everything works as normal.
        # Submitted by: ElliotHaughin

        ErrorDocument 404 index.php
    </IfModule>

    # URL and hash rewrite for backbone
    # Used for HTML 5 pushState support *NOT WORKING*
    <ifModule mod_rewrite.c>
        RewriteEngine On
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteCond %{REQUEST_FILENAME} !-d
        RewriteCond %{REQUEST_URI} !index
        RewriteRule (.*) index.html [L]
    </ifModule>

/* РЕДАКТИРОВАТЬ */

После сравнения файла .htaccess нерабочего сервера с рабочим сервером.htaccess я не добился успеха, так как оба файла были практически одинаковыми, за исключением некоторого учета путей к подпапкам. То есть:

Рабочий сервер: RewriteRule ^(.*)$ index.php?/$1 [L] Нерабочий сервер: RewriteRule ^(.*)$ dj24/index.php?/$1 [L]

И это единственная разница между двумя файлами, но это имеет смысл, потому что версия клиента (рабочий .htaccess) размещается на поддомене без подпапки, т.е. http://subdomain.ClientsDomain.com/, тогда как наша версия сервера разработки размещает проект на пути подпапки к поддомену, т.е. http://dev.Our_Domain.com/OurApplication

Я начинаю верить, что проблема связана с комбинацией поддомен + подпапка. Любая помощь в этом будет оценена по достоинству. Спасибо!


person DrewT    schedule 27.06.2014    source источник
comment
Проблема не в вашем внешнем коде, а в сервере. Сервер должен поддерживать pushState. Если у вас нет контроля над сервером ваших клиентов, почему бы вам просто не использовать URL-адреса hashchange?   -  person Cory Danielson    schedule 27.06.2014
comment
readystate4.com/2012/05 /17/ stackoverflow.com/questions/8936695/ конфигурация для каждого сервера отличается   -  person Cory Danielson    schedule 27.06.2014
comment
@CoryDanielson ах да, спасибо за ссылки. Я искал что-то о поддержке сервера для pushState и ничего не мог найти. Я предполагал, что это должно быть что-то вроде этого.   -  person DrewT    schedule 27.06.2014
comment
.htaccess для вашего нерабочего сервера отличается от других? Если вы используете .htaccess любого из серверов на этом сервере, решит ли это проблему? или это сохраняется?   -  person Lu Roman    schedule 04.07.2014
comment
@Zagen Нет, файлы .htaccess одинаковы между двумя серверами, за исключением добавленного дополнительного пути. Смотрите мой обновленный вопрос для получения подробной информации о различиях   -  person DrewT    schedule 06.07.2014
comment
Вам удалось вытащить его с помощью хэшей, но у меня вопрос, как именно не работает версия pushstate?, она не обновляет URL-адрес или обработчики, связанные с маршрутами, не срабатывают при изменении маршрута?   -  person Lu Roman    schedule 07.07.2014
comment
@Zagen - Когда он не работает, магистраль вообще не добавляет хронограф. Вот 2 снимка экрана, чтобы показать проблему - не рабочая версия (pushState оставлен): screencast.com/t/ibMWKrdL0tZ - рабочая версия (pushState удален): screencast.com/t/4cbaIcfN   -  person DrewT    schedule 07.07.2014
comment
На первом снимке экрана предполагается, что это pushstate, но маршрут такой же, как и другой. Если вы используете структуру URL, предложенную в вашем вопросе «: номер», что произойдет? Вызывается ли функция crhono? Попробуйте поместить отладчик внутри этого метода или console.log, чтобы проверить, вызывается ли он, и дайте мне знать.   -  person Lu Roman    schedule 07.07.2014


Ответы (2)


Поскольку основное различие между рабочим проектом и проектом, который не работает, заключается в структуре папок, и использование другой конфигурации для вашего httaccess не решает эту проблему, попробуйте установить корень папки на вашем маршрутизаторе, у меня была аналогичная проблема несколько месяцев назад. но я не могу точно вспомнить, чем я был (но я помню, что это было связано с использованием подпапки внутри моего домена и магистрали), так что это просто предложение, может помочь или не помочь, но в моем случае это помогло.

Сначала получите базовую папку

var baseFolder =  window.location.pathname.replace('/','').split('/')[0];

Затем используйте его в качестве корня маршрутизатора

routes: {
    '(:number)(/plus)': 'chrono'
},

initialize: function() {
    Backbone.history.start({
        pushState: true,
        hashChange: false,
        root: baseFolder                                       
    });
 },

Дайте знать, если поможет =)

person Lu Roman    schedule 07.07.2014

Вот как мне удалось решить проблему.

На проблемном сервере я настроил маршрутизатор backbone.js для приема изменений хэш-URI без использования pushState, а затем удалил условия pushState.

Вот как маршрут выглядит сейчас:

jQuery(function(){
    // define routes
    var Router = Backbone.Router.extend({
        routes: {
            '': 'chrono',
            ':number/': 'chrono', /* NOTE: ':number/' instead of the previous  ':number' */
            ':number/plus/': 'chrono' /* NOTE: ':number/plus/' instead of the previous ':number/plus' */
    },

        // load views
        initialize: function() {
            Backbone.history.start(); // pushState settings removed
    },

    // ... other router functions
    // reset: etc.

    var Router = new Router;
});

Используя эту конфигурацию, я теперь могу обрабатывать все маршруты привязки хэш-тегов моего приложения, которые я ранее обрабатывал с помощью pushState:

  • http://dev.OurDomain.com/OurAplication/chrono
  • http://dev.OurDomain.com/OurAplication/chrono#0 - http://dev.OurDomain.com/OurAplication/chrono#6 (т.е. таких пронумерованных маршрутов 7)
  • http://dev.OurDomain.com/OurAplication/chrono#0/plus - http://dev.OurDomain.com/OurAplication/chrono#6/plus (т.е. у каждого пронумерованного хеш-маршрута есть всплывающее окно модальной информации, вызываемое добавлением /plus к текущему номеру маршрута

Я также упомяну, что каждая из этих 14 ссылок имеет связанные с ней кнопки обмена Facebook и Twitter. Вот почему мы явно записываем их хэши в адресную строку, чтобы мы могли контролировать, как информация открытого графа очищается с нашего сервера. В зависимости от того, из какого раздела страницы пользователь делится/твитит, предоставляются разные данные OG. Другими словами, сколь угодно легко щелкать и перемещаться по разделам страницы для #0-6 и /plus, но цель записи их кликов непосредственно в адресную строку состоит в том, чтобы зарегистрировать информацию и миниатюры с помощью API Facebook и Twitter. Эти строки запроса могут регистрироваться в API Facebook из-за вторичной архитектуры PHP бэкэнда, которую здесь не нужно обсуждать: D

ПРЕДЛОЖНО ИМЕТЬ:

Итак, теперь все снова работает!

Я все еще ХОЧУ вернуться к версии pushState, которую мы используем на рабочем сервере нашего клиента. (Это сделано для того, чтобы анимация каждого хроно#0 (#0-6) не срабатывала во второй раз при закрытии оверлея лайтбокса, открытого маршрутами /plus.) Если кто-нибудь может понять, как это сделать< /strong> (Я предполагаю, что это подпапка .htaccess RewriteCondition или флаг, который мне не хватает) Я с радостью переназначу/назначу вам принятый ответ и связанную с ним награду.

EDIT: удалось повторно интегрировать pushState на нерабочий сервер, добавив корневой параметр в Backbone.history.start() в соответствии с ответом Zagen.

person DrewT    schedule 06.07.2014
comment
Возможно, я неправильно понимаю ваш ответ, но, насколько мне известно, Facebook не регистрирует динамические изменения (JavaScript) в тегах OG. - person steveax; 06.07.2014
comment
@steveax Это правильно, и поскольку это приложение backbone.js, обычно API Facebook не распознает ни один из маршрутов, таких как /chrono или /plus, потому что эти маршруты исходят из расширения магистрального маршрутизатора, а не из статического индекса. .php в корне проекта. Чтобы обойти это, у нас есть php-файлы, которые обслуживают модель и отображают в php на основе схемы URL-адресов, отправленной на панель URL-адресов. - person DrewT; 06.07.2014
comment
Кажется, я исправил проблему анимации chrono#1-6, которая запускалась во второй раз при закрытии окна /plus. Я только что изменил ':number': 'chrono' на ':number/': 'chrono' в своем маршрутизаторе. - person DrewT; 07.07.2014