Как отображать запросы Ajax в URL?

Я хочу иметь ссылки, которые изменяют часть страницы, и динамический URL для нее, где я могу указать такие переменные, как #calendar=10_2010tabview=tab2

Check this for an exact example: НАЖМИТЕ ЗДЕСЬ ДЛЯ ТОЧНОГО ДЕМО

Итак, вот формат ссылки, который мне нужен:

#calendar=10_2010&tabview=tab2

Мне нужны переменные в ссылках типа calendar и tabview, чтобы я мог изменять несколько вещей на одной странице без повторной загрузки.


Или другой формат, такой как http://www.wbhomes.com.au, это именно то, что я хочу, однако первый формат тоже хорош, но он намного красивее.

  • http://wbhomes.com.au/#/propertiesforsale/houseandland/quinnsbeach-waterland1

Требования

  • Требуется доступ из любого места, например, по почте, или если я просто пишу в строке URL.

  • Ссылка должна быть в истории, поэтому, если я нажму кнопку «назад» или «вперед», страница должна быть открыта.

  • Обновление страницы тоже должно работать.


Некоторые ресурсы:

Примеры:

Некоторые учебники:


Помогите, пожалуйста! Я никогда не находил решения для этого, но я не хочу использовать jquery, какой-либо API или любую библиотеку, я хочу иметь рабочий Javascript/AJAX и PHP скрипт.


person Community    schedule 08.07.2010    source источник
comment
Я не совсем слежу за тобой. Где AJAX играет с тем, что вы описываете? # Относится к привязке на странице. Я не думаю, что ты этого хочешь. Скорее всего, вам понадобится строка запроса, а затем обработайте эту сторону сервера. Вы можете использовать его на стороне клиента, и в этом случае вы должны проанализировать строку запроса URL-адреса и получить значение там.   -  person DA.    schedule 08.07.2010
comment
@DA - он говорит о том, что делает Facebook, помещая путь, запрошенный AJAX, в хэш.   -  person Matchu    schedule 08.07.2010
comment
Ajax появляется, когда содержимое изменяется, когда я нажимаю на ссылки, эта часть работает, но я не знаю, как показать изменение в URL-адресе :)   -  person Adam Halasz    schedule 08.07.2010
comment
Именно @Matchu, facebook - действительно хороший пример.   -  person Adam Halasz    schedule 08.07.2010


Ответы (7)


Для демонстрации, указанной в вашем вопросе, достижение этой функциональности на самом деле очень просто - поскольку она вообще не использует AJAX (когда вы начинаете добавлять AJAX в микс, становится сложнее - объяснено позже). Для достижения этой функциональности вам необходимо: обновите свои ссылки, чтобы использовать хеши, а затем привяжите их к событию hashchange. К сожалению, событие hashchange несовместимо с разными браузерами, хотя, к счастью, доступно множество «плагинов для истории / удаленного доступа» - за прошедшие годы мы предпочли использовать История jQuery, это открытый исходный код, большая поддержка и активное развитие :-).

Хотя, когда дело доходит до добавления функциональности AJAX к таким сайтам, как Facebook, WBHomes и Balupton.com, то вы столкнетесь с целым рядом серьезных трудностей! (Я знаю, что был ведущим архитектором двух последних сайтов!). Вот некоторые из этих проблем:

  • Как изящно и легко обновить определенные внутренние ссылки для использования функций истории и AJAX и определить, когда хэш изменился? при этом остальные ссылки работают как раньше.
  • Как выполнить перенаправление с «www.yoursite.com/myapp/a/b/c» на «www.yoursite.com/myapp/#/a/b/c»? и при этом сохранить удобство для пользователя, чтобы 3 необходимых перенаправления были максимально плавными.
  • Как отправить значения и данные формы с помощью AJAX и обновить хеш? и наоборот, если они не поддерживают Javascript.
  • Как определить, в какой именно области страницы требуется запрос AJAX? Таким образом, подстраницы отображаются с правильной страницей.
  • Как изменить заголовок страницы при изменении состояния AJAX? и другой нестраничный контент.
  • Как выполнять красивые вступительные / конечные эффекты при загрузке и изменении состояния AJAX? таким образом, чтобы пользователь не оставался в темноте.
  • Как обновить информацию для входа в боковую панель при входе в систему через AJAX? Очевидно, что мы не хотим, чтобы эта кнопка входа в систему в левом верхнем углу больше была там.
  • Как по-прежнему поддерживать веб-сайт для пользователей, у которых не включен JS? Таким образом, он постепенно ухудшается и по-прежнему индексируется поисковыми системами.

Единственный известный мне надежный проект с открытым исходным кодом, который пытается решить все упомянутые чрезвычайно сложные проблемы, оказался jQuery Ajaxy. По сути, это расширение упомянутого ранее проекта jQuery History, обеспечивающее красивый элегантный высокоуровневый интерфейс для добавления функциональности AJAX в микс, позволяющий решать эти сложные проблемы за кулисами, поэтому нам не нужно о них беспокоиться. Это также выбранное решение, используемое на нескольких последних коммерческих сайтах, упомянутых ранее.

Удачи, и если у вас есть дополнительные вопросы, просто оставьте комментарий к этому ответу, и я займусь этим как можно скорее :-)

Обновление: теперь существует API истории HTML5 (pushState, popState), который не поддерживает функциональность HTML4 hashchange. History.js теперь является преемником jQuery History и обеспечивает кроссбраузерную совместимость для HTML5 History API. и необязательный hashchange резервный вариант для браузеров HTML4. jQuery Ajaxy будет обновлен до History.js

person Community    schedule 18.07.2010
comment
Привет! Большое спасибо за ваш ответ, я знаю, что моя демонстрация не создана с использованием AJAX, однако я буду использовать AJAX, чтобы создать свою собственную, но эта демонстрация демонстрирует эффект, которого я хочу достичь, ваш пример: http://wbhomes.com.au/#/home очень круто, это на 100% так, как я хотел, без ? и тому подобного, но для меня любая версия хороша тем, что работает, однако, если бы вы могли показать мне, как вы это сделали, я был бы очень очень рад :). И я знаю, что это чрезвычайно сложно, потому что никто ничего об этом не публиковал (я не нашел), и я действительно не знаю, как это сделать, я не профессионал в javascript. - person Adam Halasz; 18.07.2010
comment
Спасибо, дружище, и я рад, что помог. Да, я полностью согласен, что сайт wbhomes очень крутой! Я отредактировал свой пост, чтобы перейти к решению, используемому для него (jQuery Ajaxy), так что это должно прояснить все, что осталось недосказанным :-) Если вы хотите узнать что-то еще, определенно не стесняйтесь оставлять комментарий, или вы всегда можете свяжитесь со мной прямо на моем веб-сайте www.balupton.com - person balupton; 27.08.2010
comment
Привет @balupton! Ajaxy - это здорово и круто, но я думаю, что с этим есть большая проблема. Я не могу указать, где я хочу поместить content. Так, например, у меня есть link1 - onclick calls page1.php и link2 - onclick calls page2.php, но я хочу link1 изменить div content1 и link2 изменить div content2, надеюсь, вы понимаете, о чем я говорю :) Думаю, с этой функцией было бы почти идеально;) - person Adam Halasz; 21.09.2010
comment
И еще кое-что, например, у меня есть search, я пишу в нем balupton, затем отправляю, затем ajaxy изменяет содержимое, но URL-адрес не изменяется. - person Adam Halasz; 21.09.2010
comment
И еще кое-что, если бы вы могли сделать это на простом Javascript, было бы здорово! Думаю, если бы вы могли это сделать, Ajaxy стал бы одним из самых полезных и мощных инструментов для разработчиков, которые хотят создавать приложения на базе Ajax :) - person Adam Halasz; 21.09.2010
comment
Привет @Cirk. Хорошие моменты и определенно кое-что, о чем я тоже думал. Его кодирование на ванильном JS и использование адаптеров для фреймворков входит в список задач. Текущим приоритетом является выпуск CMS, на котором работает balupton.com, и документирование того, как делать некоторые действительно продвинутые / изящные вещи с помощью Ajaxy. Что касается ваших баллов, сможете ли вы поднять их на сайте поддержки Ajaxy здесь getsatisfaction.com/balupton/products / balupton_jquery_ajaxy, так я буду лучше подготовлен к решению проблем :-) Здесь уже довольно поздно, поэтому я иду спать. Но очень рад, что эта колонна идет! - person balupton; 21.09.2010
comment
Спасибо за быстрый ответ @baluton! Я рад слышать, что вы хотите это сделать! Я очень счастлив и очень ценю ваш тяжелый труд! Спокойной ночи! - person Adam Halasz; 21.09.2010

Я думаю, вы можете сделать это очень легко, используя событие onHashChange, присутствующее в HTML5, или используя библиотеку JavaScript, которая имитирует это «хеш-поведение» в браузерах, которые не имеют полной поддержки HTML 5. Одной из таких библиотек может быть MooTools onhashchange, но есть и многие другие.

Than if you have a HTML 5 aware browser, or such library that emulates the behavior just use:

window.sethash("#newsection");
to change to something new from javascript, and/or a callback to that onHashChange event to intercept it, depending on your use case scenarios.

person Community    schedule 18.07.2010
comment
В самом деле, большинство пользователей используют onhashchage, включая Gmail. - person A. Ionescu; 19.07.2010
comment
Проблема в том, что onhashchage изначально не поддерживается многими браузерами или у них есть причуды. Предоставляемые библиотеки добавляют поддержку устаревших браузеров, плюс это только для подключения к хешу, а не столько для работы парадигм AJAX. - person balupton; 19.07.2010

CorMVC Jquery Framework выполнен таким образом, это с открытым исходным кодом, вы можете покопайтесь в источнике и извлеките из него логику.

И на самом деле это довольно просто. Создатель прекрасно рассказывает об этом на видео ниже.

http://www.bennadel.com/resources/jing/2009-12-21_0933.swf

PS извините, не могу разместить вторую ссылку, т.к. я новый пользователь.

person Community    schedule 18.07.2010

Севаш .. :)

HTML

<a href="/bye.php?user=abc&page=messages" 
   onclick="return goToWithAjax(this);">bye</a> 

Javascript

function goToWithAjax(hash) {
  hash = hash.href ? hash.getAttribute("href", 2) : hash;
  ajax( hash, function( response ) {
    document.getElementById("content").innerHTML = response;
  });
  hash = ("#!/" + hash).replace("//","/");
  window.location.hash = hash;
  return false;
}

//////////////////////////////////////////////////////////////////////////////

function getXmlHttpObject() {
    var xmlHttp;
    try {
        xmlHttp = new XMLHttpRequest();
    } catch (e) {
        try {
            xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
        } catch (e) {
            xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
        }
    }
    return xmlHttp;
}

function ajax(url, onSuccess, onError) {
    var xmlHttp = getXmlHttpObject();
    xmlHttp.onreadystatechange = function () {
        if (this.readyState == 4) {
            // onError
            if (this.status != 200) {
                if (typeof onError == 'function') {
                    onError(this.responseText);
                }
            }
            // onSuccess
            else if (typeof onSuccess == 'function') {
                onSuccess(this.responseText);
            }
        }
    };
    xmlHttp.open("GET", url, true);
    xmlHttp.send(null);
    return xmlHttp;
}​
person gblazex    schedule 08.07.2010
comment
Привет, @galambalazs, спасибо за скрипт, попробую! Севаш: D - person Adam Halasz; 08.07.2010
comment
А что, если у меня что-то есть до #hello? пример: example.com/?ice=cream#best - person Adam Halasz; 08.07.2010
comment
посмотрите мое обновление, теперь у вас есть довольно общее решение. :) Вы можете использовать имена файлов или URL-адреса с хешами. В этом случае вы также можете указать расширение файла, по умолчанию это php. - person gblazex; 08.07.2010
comment
URL-адрес не меняется. : S вот как я это использовал: <a href="http://192.168.2.104/?user=<?php echo $user->username?>#messages" onclick="return goToWithAjax('http://192.168.2.104/pages/messages.php');">messages</a> - person Adam Halasz; 08.07.2010
comment
Ммм .. нет, как я уже сказал, URL не меняется, когда я click на link. Но содержание меняется :) - person Adam Halasz; 08.07.2010
comment
Хорошо, давайте разберемся. Вы можете изменить хэш-часть URL-адреса только в том случае, если хотите остаться на той же странице. <a href="#messages" onclick="goToWithAjax(this)">messages</a>. Таким образом, вы не можете изменить то, что находится в строке URL, кроме части #hash, потому что если вы это сделаете, вы перенаправите пользователя на другую страницу (и вы нарушите суть ajax) - person gblazex; 08.07.2010
comment
Facebook делает это http://www.facebook.com/#!/home.php?sk=bd это совсем не то, что вы просили - person gblazex; 08.07.2010
comment
если я напишу onclick="goToWithAjax(this), ничего не произойдет, содержимое останется пустым, и URL тоже не изменится. - person Adam Halasz; 08.07.2010
comment
Ну, я имею в виду, как это работает, не зная каких-либо фоновых вещей, когда вы нажимаете на ссылку, URL меняется, и часть content тоже, все остальное остается прежним. я тоже этого хочу. http://192.168.2.104/?user=galambalazs#messages - person Adam Halasz; 08.07.2010
comment
Но затем вы открываете messages.php, но он не узнает, какой пользователь выбран на странице. Потому что это два разных запроса. - person gblazex; 08.07.2010
comment
Я хочу позже получить идентификатор сообщения, как мне это сделать, для меня версия facebook хороша, так как она идеальна, но как я могу это сделать? - person Adam Halasz; 08.07.2010
comment
Risten! Оно работает! но вот как URL выглядит после того, как я щелкнул по нему: http://192.168.2.104/?user=Adam#/#!/http:/192.168.2.104/pages/messages.php?user=Adam&page=messages, вот как я использовал <a>: <a href="http://192.168.2.104/page/messages.php?user=<?php echo $user->username?>&page=messages" onclick="return goToWithAjax(this);">messages</a>, в чем проблема? - person Adam Halasz; 08.07.2010
comment
Или вы так его создали? взять полный url? - person Adam Halasz; 08.07.2010
comment
и еще кое-что. В моем базовом вопросе я написал, что к URL нужно обращаться откуда угодно, из почты или, если я напишу его вручную, здесь это не работает: S - person Adam Halasz; 08.07.2010
comment
ммм и перезагрузка тоже не работает: S, но я очень рад, что контент + url тоже меняется: D - person Adam Halasz; 09.07.2010
comment
Вам нужно обрабатывать эти вещи на стороне сервера (PHP). Это то, что делает facebook. Итак, вы берете $_SERVER['REQUEST_URI'], sth как: $hash = array_pop(explode('#', $_SERVER['REQUEST_URI']));, тогда у вас есть часть URL-адреса AJAX, и вы можете соответственно загружать контент. - person gblazex; 09.07.2010
comment
Значит, я должен добавить $hash к ссылке? что-то вроде этого? <a href="<?php echo $hash ?>&page=messages"> Я пробовал это, но не работает. Я включил PHP, этот способ работает, но включает всю страницу (возможно, это просто моя ошибка), но я все еще не могу перезагрузить страницу и перейти к ней напрямую. - person Adam Halasz; 09.07.2010
comment
no $hash не будет содержать часть URL-адреса AJAX, например home.php?user=galambalazs, и зная, что вы можете сгенерировать контент. - person gblazex; 09.07.2010
comment
так где я должен положить $hash? в messages.php или где? - person Adam Halasz; 09.07.2010
comment
на каждый сайт, на котором вы используете ajax. Это поможет вам восстановить вещи с помощью ajax. Например, когда пользователь переходит по ссылке. - person gblazex; 09.07.2010
comment
Ahh na ezt magyarul: D Mostmár megkerdülök itt mert nem értem. xD Nem értem hogy hogyan kell használni a $hash-t, файл amit megkéne hívjon az ajax az a messages.php, azokba a fileokba kéne rakjam amiket meghív az ajax? és ha igen akkor ott mit csináljak vele? - person Adam Halasz; 09.07.2010
comment
@cir: Не могли бы вы оставить его на английском, чтобы другие люди могли следить за ним? - person Georg Fritzsche; 19.07.2010
comment
@George Fritzsche, конечно, вот что я сказал: я не понимаю, как использовать $ hash, файл, который ajax должен включить, - это messages.php. Нужно ли мне помещать $hash в файлы, которые предлагает ajax? если да, то что мне с этим делать? - person Adam Halasz; 19.07.2010

Это то, что ускользает от большинства новых разработчиков AJAXian. Но решить эту проблему довольно просто.

Первое, что вам понадобится, это ядро ​​jQuery, которое бесплатно на jquery.com

Затем вам понадобится плагин для изменения хэша jQuery от Бена Алмана, который вы можете найти здесь: http://benalman.com/projects/jquery-hashchange-plugin/ Вам это не понадобится для новых версий браузеров, которые поддерживают событие hashchange html5, но вам это понадобится для более старых версий браузеров. Вам не нужно ничего делать, кроме как включить этот скрипт на свою страницу, все остальное он сделает за вас.

Теперь для ваших ссылок вам нужно будет построить их в виде строки запроса следующим образом:

<a href="user.php?q=/topic/article" class="dynlnk">Link Text/Image</a>

теперь у вас есть ссылки, которые ведут на страницы и могут обрабатываться на php, если javascript отключен. все, что вам нужно сделать, это использовать суперглобальный $ _GET и проанализировать строку запроса для обработки содержимого страницы.

теперь в вашем javascript на странице вам нужно будет заставить ваши ссылки запускать hashchange. Вы можете сделать это, заменив? Q = на такой #.

$(".dynlnk").each(function(){
    $(this).attr("href", $(this).attr("href").replace("?q=", "#"));
});

теперь ваши ссылки будут запускать hashchange, осталось только привязать hashchange к функции, которая что-то делает. Это можно сделать очень просто с помощью jQuery следующим образом:

$(window).bind( 'hashchange', function(e){

    //this splits the part after the hash so you can handle the parts individually.
    //to handle them as one just use location.hash
    pageparts = location.hash.split("/");

});

Теперь просто добавьте любой код, который вы делаете для обработки вашего ajax и контента.

теперь вам просто нужен последний бит javascript для запуска хеш-обмена в случае, если страница была загружена с хешем для начала, поэтому вы просто вызываете функцию триггера Windows при загрузке страницы

$(window).trigger( 'hashchange' );

Надеюсь, это достаточно ясно, если нет, не стесняйтесь обращаться ко мне, чтобы задать больше вопросов.

person Community    schedule 20.07.2010

Использование хеш-ссылок позволяет закладкам / ссылкам для совместного использования запускать код JavaScript вместо перезагрузки страницы. Событие jQuery hashchange Бена Алмана позволяет связать обработчик событий с событием hashchange, этот плагин работает со старыми браузерами, которые обычно не поддерживают это. Обработчик событий, связанный с hashchange, может читать хеш-часть URL-адреса и вызывать любую функцию.

// register event handler
function bindHashchange() {

    $(window).bind('hashchange', function(event) {
        event.preventDefault();
        var label = location.hash.substring(1);
        handleLabel(label);
    });

    // trigger event so handler will be run when page is opened first time
    // otherwise handler will only run when clicking on hash links
    $(window).trigger('hashchange');
}

// read and handle hash part of url
function handleLabel(label) {

    if ( label.length > 0 ) {
        // using label from url
        switchPage(label);
    } else {
        // use the default label, if no hash link was present
        switchPage('start');
    }
}

// in this case, load hidden <div>'s into a <div id="content">
function switchPage(label) {
    if ( label == 'start ) {
        $('div#content').html($('div#start'));
    } else if ( label == 'some_other_page' ) {
        // do something else
    }
}

Этот другой обработчик событий может обрабатывать 2 аргумента, разделенных точкой ('.') В одном и том же URL-адресе.

function processHash() {

    var str = location.hash.substring(1);
    var pos = $.inArray('.', str);

    var label = '';
    var arg = '';

    if ( pos > -1 ) {
        label = str.substring(0, pos);
    } else {
        label = str.substring(0);
    }

    if ( pos > 1 ) {
        arg = str.substring(pos+1);
    }

    if ( label.length == 0 ) {
        // the default page to open of label is empty
        loadContent('start');
    } else {
        // load page, and pass an argument
        loadContent(label, arg);
    }
}

Если используются регулярные выражения, можно анализировать любую комбинацию символов.

var registry = {};

// split on character '.'
var args = label.split(/\./g);

for ( i in args ) {
    var arg = args[i];

    // split on character '='
    var temp = arg.split('=');
    var name = temp[0];
    var value = temp[1];

    // store argument in registry
    registry[name] = value;
}
// registry is loaded, ready to run application that depends on arguments

Это преобразует URL-адрес:

mysite / # company.page = items.color = красный

В следующий объект JavaScript:

Объект {company = undefined, page = "items", color = "red"}

Тогда остается только запустить функции jQuery show () или hide () для выбранных вами элементов.

Его можно преобразовать в JavaScript, отличный от jQuery, но тогда вы потеряете функциональность, предоставляемую Беном Алманом, что имеет решающее значение для портативного решения.

person Community    schedule 23.07.2010

Вам нужен способ поддерживать историю в AJAX, что можно сделать с использованием многих уже существующих библиотек. Я бы рекомендовал прочитать страницу YUI 3 по истории.

person Community    schedule 24.07.2010