Jak indexovat AJAX? Shebangem #!

před 6 lety napsal Jan Havrda | tagy: AJAX SEO

Ajaxové aplikace jsou indexovatelné ve vyhledávačích, pokud dokážete jednotlivé stavy aplikace vyjádřit vlastní adresou a poskytovat je jak dynamicky pro prohlížeče tak i staticky pro vyhledávače.

Shebang (hashbang) je zkratka pro sekvenci znaků mřížka „hash“ a vykřičník „bang“ – tj. #!. Používá se v linuxu jako příkaz interpreteru (#!/bin/sh), ale našla si cestu i do internetových adres URL – jako například u Twitteru http://twitter.com/#!/search/test.

URL obsahující shebang (#!) mají tři důležité vlastnosti:

  • část za hashem lze upravovat javascriptem přes location.hash, bez reloadu stránky
  • webové servery část URL za mřížkou nepřijímají
  • vyhledávače dokáží tyto adresy indexovat

URL s shebangem lze indexovat v případě, že danou adresu dokážeme poskytnout ve dvou krocích (ze serveru a pak pomocí AJAXu), tak i v kompletní podobě přímo ze serveru .

  • v prohlížeči se načte adresa s shebangem http://twitter.com/#!/search/test, server podá část před mřížkou http://twitter.com a přes AJAX se doplní obsah za mřížkou /search/test
  • vyhledávače mají k dispozici stránku http://twitter.com/?_escaped_fragment_=/search/test s kompletním obsahem

Varianta adresy s parametrem _escaped_fragment_ slouží pouze pro interní použití vyhledávačů. Jedinou platnou a publikovanou URL je verze s shebangem (#!).

Použití shebangu je snadné v případě, že stránky jsou z větší části renderovány na serveru – viz příklad níže nebo demo. V případě, že je k sestavení stránky hodně javascriptového kódu v prohlížeči, může vám pomoci bezhlavičkový prohlížeč HtmlUnit

Více o procházení ajaxového obsahu na code.google.com

<?php
        ob_start();
?>

<html>
        <head>
                <script type="text/javascript" src="http://mootools.net/assets/scripts/mootools.core.js"></script>
                <script type="text/javascript">

                        window.addEvent('domready',function(){
                                        var str = location.hash.replace(/\#\!hello=/,'');
                                        if(location.hash != str){
                                                hello(str);
                                                $('input').value = str;
                                        }
                                }
                        );

                        function hello(str){

                                location.hash = '#!hello=' + str;

                                if(location.href.match(/escaped_fragment/)) location.href = 'shebang.php' + location.hash;

                                new Request({
                                        url: 'shebang.php',
                                        data:{hello: str},
                                        onSuccess: function(event, xhr) {
                                                $('hello').set('html',event)
                                                }
                                        }).send();

                        }
                </script>
        </head>
        <body>
                <h1>Ajaxová pozdravovací aplikace</h1>
                <h2 id="hello">{html}</h2>
                Ahoj <input type="text" id="input" value="{html}"/>
                <button onclick="hello($('input').value);return false;">Proveď Ajax</button><br/>
                <a href="#" onclick="location = 'shebang.php?_escaped_fragment_=hello%3D' + $('input').value">Nahraj jako vyhledávač</a>
                <a href="shebang.php">Výchozí stránka</a>
        </body>
</html>


<?php

$html = ob_get_clean();

switch(true){
        case(isset($_POST['hello'])): // AJAX
                echo $_POST['hello'];
                break;

        case(strpos($_GET['_escaped_fragment_'],'hello') === 0): // vyhledávač
                $hello = str_replace('hello=','',$_GET['_escaped_fragment_']);
                echo str_replace('{html}',$hello,$html);
                break;

        case(!count($_POST) && !count($_GET)): // úvod
                echo str_replace('{html}','',$html);
}