javascript .htaccess web-crawler single-page-application

javascript - .htaccess para SEO bots que rastrea aplicaciones de una página sin hashbangs



web-crawler single-page-application (4)

Tuve un problema similar en una aplicación web de una sola página.

La única solución que encontré para este problema fue la creación de versiones estáticas de páginas con el propósito de hacer algo navegable por los bots de Google (y otros).

Puede hacerlo usted mismo, pero también hay servicios que hacen exactamente esto y crean su caché estática para usted (y sirven las instantáneas a los bots a través de su CDN).

Terminé usando SEO4Ajax, ¡aunque hay otros servicios similares disponibles!

Al usar una página activada por pushState , normalmente se redirigen los bots de SEO utilizando la convención escaped_fragment . Puedes leer más sobre eso aquí .

La convención asume que usará un prefijo hashbang ( #! ) Antes de todos sus URI en una aplicación de una sola página. Los robots de SEO escaparán de estos fragmentos reemplazando el hashbang con su propia convención reconocible escaped_fragment al hacer una solicitud de página.

//Your page http://example.com/#!home //Requested by bots as http://example.com/?_escaped_fragment=home

Esto le permite al administrador del sitio detectar bots y redirigirlos a una página previamente procesada en caché.

RewriteCond %{QUERY_STRING} ^_escaped_fragment_=(.*)$ RewriteRule ^(.*)$ https://s3.amazonaws.com/mybucket/$1 [P,QSA,L]

El problema es que el hashbang se está eliminando rápidamente con el soporte pushState ampliamente adaptado. También es muy feo y no es muy intuitivo para un usuario.

Entonces, ¿qué pasa si utilizamos el modo HTML5 donde pushState guía a toda la aplicación del usuario?

//Your index is using pushState http://example.com/ //Your category is using pushState (not a folder) http://example.com/category //Your category/subcategory is using pushState http://example.com/category/subcategory

¿Puede reescribir reglas para guiar bots a su versión almacenada en caché utilizando esta nueva convención? Relacionadas pero solo cuentas para el caso del borde del índice. Google también tiene un artículo que sugiere usar un método opt-in para este caso único utilizando <meta name="fragment" content="!"> En el <head> de la página. De nuevo, esto es para un caso de borde único. Aquí estamos hablando de manejar cada página como un senario de aceptación.

http://example.com/?escaped_fragment= http://example.com/category?escaped_fragment= http://example.com/category/subcategory?escaped_fragment=

Estoy pensando que el escaped_fragment todavía se puede usar como un identificador para los robots de SEO, y que podría extraer todo lo que está entre el dominio y este identificador para agregar a mi ubicación de depósito como:

RewriteCond %{QUERY_STRING} ^_escaped_fragment_=$ # (high level example I have no idea how to do this) # extract "category/subcategory" == $2 # from http://example.com/category/subcategory?escaped_fragment= RewriteRule ^(.*)$ https://s3.amazonaws.com/mybucket/$2 [P,QSA,L]

¿Cuál es la mejor manera de manejar esto?


Estaba teniendo exactamente el mismo problema. Por ahora, modifiqué .htaccess así:

RewriteCond %{QUERY_STRING} ^_escaped_fragment_=(.*)$ RewriteRule ^$ /snapshots/index.html? [L,NC] RewriteCond %{QUERY_STRING} ^_escaped_fragment_=(.*)$ RewriteRule ^(.*)$ /snapshots/$1.html? [L,NC]

No estoy seguro de si hay una solución mejor, pero hasta ahora me funciona. Solo asegúrese de que la estructura del directorio de sus instantáneas coincida con la estructura de la URL.


Estoy usando PhantomJS para generar instantáneas estáticas de mis páginas. Mi estructura de directorios solo tiene un nivel de profundidad ( root y /projects ), así que tengo dos archivos .htaccess, en los que index-bots.php a un archivo PHP ( index-bots.php ) que inicia un proceso PhantomJS apuntando a mi SPA index.html e imprime las páginas estáticas renderizadas.

Los archivos .htaccess se ven así:

/.htaccess

# redirect search engine bots to index-bots.php # in order to serve rendered HTML via phantomjs RewriteCond %{HTTP_USER_AGENT} (bot|crawl|slurp|spider) [NC] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_URI} !^/index-bots/.php [NC] RewriteRule ^(.*)$ index-bots.php?url=%{REQUEST_URI} [L,QSA]

/projects/.htaccess

# redirect search engine bots to index-bots.php # in order to serve rendered HTML via phantomjs RewriteCond %{HTTP_USER_AGENT} (bot|crawl|slurp|spider) [NC] RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.*)$ ../index-bots.php?url=%{REQUEST_URI} [L,QSA]

Un par de notas:

  • !-f El !-f RewriteCond es crítico! Como .htaccess aplicará RewriteRule a todas las solicitudes, los recursos de su página se reescribirán en el archivo PHP, haciendo girar varias instancias de PhantomJS y poniendo a su servidor de rodillas.
  • También es importante eximir index-bots.php de las reescrituras para evitar un ciclo sin fin.
  • Saco el JS en mi script PhantomJS runner, para asegurarme de que JS no haga nada cuando los bots que lo soportan se encuentran con las páginas "estáticas".
  • No soy asistente de .htaccess, por lo que probablemente haya una mejor manera de hacerlo. Me encantaría escucharlo si es así.

Estoy usando Symfony2, y aunque otros desarrolladores me dicen que Googlebot y Bingbot ejecutan Javascript lo suficientemente bien como para generar sus propios fragmentos de HTML, no me siento seguro. También creo que el servicio de recursos estáticos es una mejor alternativa para personas que se ejecutan con JS apagado (por improbable que sea) y, por lo tanto, estoy interesado en servir fragmentos de HTML de todos modos, siempre que no sea una molestia. A continuación se muestra un método que estoy pensando en usar pero que no he intentado:

Aquí hay otras preguntas similares que son similares (una es mía).
Angularjs vs SEO vs pushState
¿Fragmentos de HTML para la aplicación AngularJS que usa pushState?

Aquí hay una solución que publiqué en esa pregunta y estoy considerando por mí mismo en caso de que quiera enviar fragmentos de código HTML a los bots. Esta sería una solución para un backend Symfony2 :

  1. Use prerender u otro servicio para generar fragmentos estáticos de todas sus páginas. Guárdelos en un lugar accesible por su enrutador.
  2. En su archivo de enrutamiento Symfony2, cree una ruta que coincida con su SPA. Tengo un SPA de prueba ejecutándose en localhost.com/ng-test/, por lo que mi ruta se vería así:

    # Adding a trailing / to this route breaks it. Not sure why.
    # This is also not formatting correctly in . This is yaml.
    NgTestReroute:
    ----path: /ng-test/{one}/{two}/{three}/{four}
    ----defaults:
    --------_controller: DriverSideSiteBundle:NgTest:ngTestReroute
    --------''one'': null
    --------''two'': null
    --------''three'': null
    --------''four'': null
    ----methods: [GET]

  3. En su controlador Symfony2, verifique user-agent para ver si es googlebot o bingbot. Debería poder hacer esto con el siguiente código y luego usar esta lista para apuntar a los bots en los que está interesado ( http://www.searchenginedictionary.com/spider-names.shtml ) ...

    if(strstr(strtolower($_SERVER[''HTTP_USER_AGENT'']), "googlebot"))
    {
    // what to do
    }

  4. Si su controlador encuentra una coincidencia con un bot, envíele el fragmento de HTML. De lo contrario, como en el caso de mi aplicación AngularJS, simplemente envíe al usuario a la página de índice y Angular hará el resto correctamente.

Además, si su pregunta ha sido respondida, seleccione una para que yo y otros podamos decir qué funcionó para usted.