Bienvenue à Blogs CodeS-SourceS Identification | Inscription | Aide

Atteint de JavaScriptite Aiguë [Cyril Durand]

Expert ASP.net Ajax et WCF, Cyril Durand parle dans son blog de point techniques sur ASP.net, ASP.net Ajax, JavaScript, WCF et .net en général. Cyril est également consultant indépendant, n'hésitez pas à le contacter pour de l'assistance sur vos projets

Actualités

  • Blog de Cyril DURAND, passionné de JavaScript, Ajax, ASP.net et tout ce qui touche au developpement Web Client-Side.

    N'hésitez pas à me contacter pour vos projets .net : architecture, accompagnement, formation, ...

    View Cyril Durand's profile on LinkedIn
    hit counters


    Expertise Commerce server et BizTalk

Référencement et UpdatePanel : la solution CrawlableLinkButton

Les UpdatePanels sont très agréables pour l'utilisateur puisque, bien utilisés, ils permettent d'avoir une expérience utilisateur plus fluide. Pour arriver à ce résultat, ils utilisent une requête XMLHttpRequest (requête Ajax) qui n'est pas référençable par les moteurs de recherche.

Comment utiliser les UpdatePanels sans sacrifier son référencement ? 

Pour qu'un utilisateur puisse utiliser les résultats du moteur de recherche, il faut que le contenu soit accessible à partir d'une requête GET, lorsque l'utilisateur clique il faut qu'il arrive directement sur ce qui l'intéresse, ce n'est pas le cas si on utilise les UpdatePanels avec un LinkButton.

Prenons un exemple : une page qui liste les processus en cours sur la machine et qui affiche le détail du processus sélectionné :

<script type="text/C#" runat="server"> void Page_Load(Object sender, EventArgs e) { if (!Page.IsPostBack) { BindData(); } } private System.Diagnostics.Process _currentProcess; public System.Diagnostics.Process CurrentProcess { get { if (_currentProcess == null) { int pid = -1; if (Page.IsPostBack) { if (ViewState["PID"] != null) { pid = (int)ViewState["PID"]; } } else { int.TryParse(Request.QueryString["PID"], out pid); } if (pid > -1) { _currentProcess = Processes.Find(delegate( System.Diagnostics.Process process){ return process.Id == pid; }); } else { _currentProcess = Processes[0]; } } return _currentProcess; } set { ViewState["PID"] = value.Id; _currentProcess = value; } } private static List<System.Diagnostics.Process> _processes; public static List<System.Diagnostics.Process> Processes { get { // Ne faites pas ça, c'est pour l'exemple mais attention // c'est pas thread safe ... if (_processes == null) { _processes = new List<System.Diagnostics.Process>( System.Diagnostics.Process.GetProcesses()); } return _processes; } } void gvProcess_SelectedIndexChanged(object sender, EventArgs e) { // ca aussi c'est mal, c'est pour simplifier l'exemple CurrentProcess = Processes[gvProcess.SelectedIndex]; } void BindData() { gvProcess.DataSource = Processes; gvProcess.DataBind(); } </script> <asp:Content ID="Content1" ContentPlaceHolderID="CPH1" runat="Server"> <asp:UpdatePanel runat="server" UpdateMode="Conditional" > <ContentTemplate> <%=CurrentProcess.ProcessName %> </ContentTemplate> <Triggers> <asp:AsyncPostBackTrigger ControlID="gvProcess" /> </Triggers> </asp:UpdatePanel> <asp:GridView runat="server" ID="gvProcess" AutoGenerateColumns="false" OnSelectedIndexChanged="gvProcess_SelectedIndexChanged"> <Columns> <asp:CommandField ShowSelectButton="true" /> <asp:BoundField DataField="ProcessName" /> <asp:BoundField DataField="VirtualMemorySize" /> </Columns> </asp:GridView> </asp:Content>

Cette page fonctionne parfaitement, mais regardons le code html généré au niveau d'une ligne d'un gridview.

<tr class="AspNet-GridView-Alternate"> <td><a href="javascript:__doPostBack('ctl00$CPH1$gvProcess','Select$15')">Select</a></td> <td>WebDev.WebServer</td> <td>283324416</td> </tr>

Le détail de ce processus ne peut pas être indexé par un robot. Même si un robot était capable d'exécuter JavaScript et donc de lire le détail du processus, comment ferait-il ressortir ce résultat ? Lorsque l'utilisateur fais une recherche il veut voir directement le contenu qui l'intéresse : il faut que la contenu soit accessible à partir d'une URL.

Comment contourner le problème ? L'idée est d'exécuter le postback donc du JavaScript pour les clients riches tout en laissant une vrai url pour les robots.

Ainsi la ligne plus haut se transformerait en :

<tr class="AspNet-GridView-Alternate"> <td> <a href="temp.aspx?PID=1092" onclick="void(__doPostBack('ctl00$CPH1$gvProcess$ctl17$ctl00',''));return false;"> Select </a> </td> <td>WebDev.WebServer</td> <td>285884416</td> </tr>

Pour arriver à ce résultat, j'ai créé un contrôle héritant de LinkButton : le CrawlableLinkButton qui rajoute la propriété NavigateUrl. Les sources du contrôle CrawlableLinkButton se trouve sur aspfr.

Le gridview se transforme alors en

<asp:GridView runat="server" ID="gvProcess" AutoGenerateColumns="false" OnSelectedIndexChanged="gvProcess_SelectedIndexChanged"> <Columns> <asp:TemplateField> <ItemTemplate> <cs:CrawlableLinkButton runat="server" CommandName="Select" Text="Select" NavigateUrl='<%# "temp.aspx?PID=" + Eval("id").ToString() %>' /> </ItemTemplate> </asp:TemplateField> <asp:BoundField DataField="ProcessName" /> <asp:BoundField DataField="VirtualMemorySize" /> </Columns> </asp:GridView>

On voit qu'avec un minimum de code (le CrawLableLinkButton ne fait pas 100 lignes) il est possible de trouver des solutions pour référencer des UpdatePanels, il suffit de se mettre à la place d'un moteur de recherche et analyser le code HTML.

Posted: mardi 16 octobre 2007 12:43 par cyril
Ce post vous a plu ? Ajoutez le dans vos favoris pour ne pas perdre de temps à le retrouver le jour où vous en aurez besoin :

Commentaires

guitoux1 a dit :

"On voit qu'avec un minimum de code (le CrawLableLinkButton ne fait pas 100 lignes) il est possible de trouver des solutions pour référencer des UpdatePanels, il suffit de se mettre à la place d'un moteur de recherche et analyser le code HTML."

... et aussi créer la page temp.aspx qui permettra d'afficher le contenu à référencer :)

# octobre 16, 2007 14:25

cyril a dit :

Dans mon exemple, la page temp était celle qui contient l'UpdatePanel ;-). Il a aussi fallu que je change la méthode CurrentProcess pour prendre en compte le querystring mais 2 lignes de codes à rajouter.

On peut bien sur faire 2 pages différentes et utiliser des UserControls pour ne pas réécrire la partie de détail, ou alors fournir un contenu complétement différent entre l'updatepanel et la page de destination, bref ce n'est pas quelque chose de compliqué ;-)

# octobre 16, 2007 14:52

Aurelien a dit :

Et ca marche, c'est exactement le stratagème que j'ai mis en place sur le site wygwam en 2005 ;-)

Pas d'updatepanel en cause, mais de simples requêtes XmlHttp, à cette époque, on ne parlait pas encore "Atlas" !

Par contre, j'ai un moteur de rendering pour reconstruire les urls que les robots indexent ...

# octobre 17, 2007 00:29
Les commentaires anonymes sont désactivés

Les 10 derniers blogs postés

- Office 365: Script PowerShell pour auditer l’usage des Office Groups de votre tenant par Blog Technique de Romelard Fabrice le 04-26-2019, 11:02

- Office 365: Script PowerShell pour auditer l’usage de Microsoft Teams de votre tenant par Blog Technique de Romelard Fabrice le 04-26-2019, 10:39

- Office 365: Script PowerShell pour auditer l’usage de OneDrive for Business de votre tenant par Blog Technique de Romelard Fabrice le 04-25-2019, 15:13

- Office 365: Script PowerShell pour auditer l’usage de SharePoint Online de votre tenant par Blog Technique de Romelard Fabrice le 02-27-2019, 13:39

- Office 365: Script PowerShell pour auditer l’usage d’Exchange Online de votre tenant par Blog Technique de Romelard Fabrice le 02-25-2019, 15:07

- Office 365: Script PowerShell pour auditer le contenu de son Office 365 Stream Portal par Blog Technique de Romelard Fabrice le 02-21-2019, 17:56

- Office 365: Script PowerShell pour auditer le contenu de son Office 365 Video Portal par Blog Technique de Romelard Fabrice le 02-18-2019, 18:56

- Office 365: Script PowerShell pour extraire les Audit Log basés sur des filtres fournis par Blog Technique de Romelard Fabrice le 01-28-2019, 16:13

- SharePoint Online: Script PowerShell pour désactiver l’Option IRM des sites SPO non autorisés par Blog Technique de Romelard Fabrice le 12-14-2018, 13:01

- SharePoint Online: Script PowerShell pour supprimer une colonne dans tous les sites d’une collection par Blog Technique de Romelard Fabrice le 11-27-2018, 18:01