Silverlight 4 + RIA Services – Ready for Business: Tối ưu hóa tìm kiếm (SEO)


Để tiếp tục loạt bài, ta hãy xem tiếp SEO (tối ưu hóa cho các máy tìm kiếm) và Silverlight. Thông tin trên web hiện nay được dẫn dắt chủ yếu bởi các máy tìm kiếm, các máy tìm kiếm cũng là nơi dừng chân đầu tiên cho nhiều người dùng trên mạng Internet công cộng và cũng đang tăng lên trong môi trường doanh nghiệp. Tìm kiếm cũng là công nghệ chính mang đến doanh thu từ quảng cáo. Vậy nên sẽ là thừa nếu phải nói SEO quan trọng. Nhưng SEO sẽ làm việc thế nào trong các ứng dụng Silverlight khi mà hầu hết dữ liệu sẽ được sinh ra động? Tôi sẽ giới thiệu một mẫu ứng dụng để SEO trong Silverlight với chỉ những thao tác tối thiểu.

Có ba bước đơn giản để làm cho ứng dụng của bạn thân thiện với các máy tìm kiếm:

  • Bước 1: Tạo liên kết cho các nội dung quan trọng sâu bên trong.
  • Bước 2: Cho phép các máy tìm tiếm biết tất cả các thông tin về các liên kết đó với một sitemap.
  • Bước 3: Cung cấp 1 phiên bản “cấp thấp” cho các nội dung quan trọng.

Ta sẽ cùng đào sâu vào các phần trên bằng một ví dụ. Tôi dự định sẽ dùng chương trình demo của tôi trong PDC2009 “foodie Explorer” như nền tảng cơ sở. Bạn cũng có thể đọc thêm về các bước tạo nên ứng dụng này (PDC09 Talk: Building Amazing Business Applications with Silverlight 4, RIA Services and Visual Studio 2010) để có các kiến thức nền tảng trước khi ta bắt đầu.

Tải về toàn bộ ứng dụng mẫu

Bước 1: Tạo liên kết cho các nội dung quan trọng sâu bên trong

Bất kỳ nội dung nào bạn muốn có thể được tìm thấy riêng lẻ đều cần có các URL truy cập vào. Nếu tôi muốn bạn có thể dùng Bing (hay Google, hoặc bất kỳ cái nào khác) tìm “Country Fried Steak” và nhảy vào trang hình ảnh về Country Fried Steak tôi sẽ cần có một URL chỉ đến chính xác nội dung đó. http://foo.com/foodieExplorer.aspx là chưa đủ, tôi phải có một liên kết kiểu như http://foo.com/foodieExplorer.aspx?food=”Country Fried steak”. Kỹ thuật này còn mang lại nhiều lợi ích khác, như là người dùng có thể tweet, email và IM các URL để thảo luận riêng về nội dung đó.

May mắn là với tính năng  Silverlight navigation, bạn có thể thêm hỗ trợ cho việc tạo các liên kết kiểu như vậy rất dễ dàng. Hãy xem cách làm điều đó trong ứng dụng Silverlight này.

image

Điều chúng ta cần làm là cung cấp một URL có thể giúp xác định một nhà hàng cụ thể cho trước. Để SEO cũng như giúp dễ đọc hơn, chúng ta muốn có một URL dạng như sau: http://www.hanselman.com/abrams/restaurant/25/plate/4, để chỉ ra rằng đây là restaurant 25 và plate 4. Để cho phép điều này, hãy định nghĩa các route trong file global.asax của ứng dụng web.

  1:     public class Global : HttpApplication
  2:     {
  3:         void Application_Start(object sender, EventArgs e)
  4:         {
  5:             RegisterRoutes(RouteTable.Routes);
  6:         }
  7:
  8:         void RegisterRoutes(RouteCollection routes)
  9:         {
 10:             routes.MapPageRoute(
 11:                 "deepLinkRouteFull",
 12:                 "restaurant/{restaurantId}/plate/{plateId}",
 13:                 "~/default.aspx",
 14:                 false,
 15:                 new RouteValueDictionary { { "restaurant", "-1" },
 16:                                            { "plate", "-1" } });
 17:
 18:             routes.MapPageRoute(
 19:                 "deepLinkRoute",
 20:                 "restaurant/{restaurantId}",
 21:                 "~/default.aspx",
 22:                 false,
 23:                 new RouteValueDictionary { { "restaurant", "-1" } });
 24:

Ở dòng 12 và 20 chúng ta định nghĩa dạng của các liên kết vào bên trong mà chúng ta hỗ trợ với restaurantId và plateId sẽ được thay thế bởi các giá trị trên URL. Chúng ta định nghĩa chúng theo thứ tự từ phức tạp nhất cho đến đơn giản nhất. Các giá trị mặc nhiên được đặt trong dòng 15 và 23 nếu các Id đã cho không có trên URL.

Giờ hãy xem cách để diễn dịch URL này trong ứng dụng Silverlight. Trong Plates.xaml.cs:

  1:         // Executes when the user navigates to this page.
  2:         protected override void OnNavigatedTo(NavigationEventArgs e)
  3:         {
  4:             int plateID = -1;
  5:             int restaurantId  =-1;
  6:             var s = HtmlPage.Document.DocumentUri.ToString().Split(new char[] {'/','#'});
  7:             int i = Find(s, "plate");
  8:             if (i != -1)
  9:             {
 10:                 plateID = Convert.ToInt32(s[i + 1]);
 11:                 plateDomainDataSource.FilterDescriptors.Add(
 12:                     new FilterDescriptor("ID",
 13:                         FilterOperator.IsEqualTo, plateID));
 14:             }
 15:             i = Find(s, "restaurant");
 16:             if (i != -1) restaurantId = Convert.ToInt32(s[i + 1]);
 17:             else restaurantId = Convert.ToInt32(NavigationContext.QueryString["restaurantId"]);
 18:             plateDomainDataSource.QueryParameters.Add(
 19:                new Parameter()
 20:                {
 21:                   ParameterName = "resId",
 22:                   Value = restaurantId
 23:                }
 24:             );
 25:         }
 26:

Về cơ bản, đoạn mã trên lấy về toàn bộ URL, sau đó tách ra từng phần và lấy về restaurantId và plateId. Trên dòng từ 18 đến 23, chúng ta truyền restaurantId như một tham số vào cho phương thức truy vấn và trong dòng 11 đến 14 ở trên, thay vì dùng phương thức truy vấn, ta áp dụng bộ mô tả bộ lọc để thêm mệnh đề “where” vào cho câu LINQ được gửi lên server. Kết quả là, chúng ta không cần thay đổi điều gì bên phía server.

Một thứ khác chúng ta cần làm là đảm bảo client nhảy đến trang Plate. Nó được xử lý bởi navigation framework của Silverlight bằng cách dùng thẻ <a> “#/Plates”. Vì thẻ <a> chỉ được dùng trên phía client, nên các máy tìm kiếm khó có thể tân dụng nó một cách hiệu quả. Vậy nên ta cần thêm một ít mã vào để xử lý trường hợp này, tôi đã tìm được một cách tương đối đơn giản với JavaScript. Tôi thêm câu lệnh sau vào trang Default.aspx trên server:

  1: protected void Page_Init(object sender, EventArgs e)
  2: {
  3:    string resId = Page.RouteData.Values["restaurant"] as string;
  4:    if (resId != null) { Response.Write("<script type=text/javascript>window.location.hash='#/Plates';</script"+">"); }
  5: }
  6:

Một điều khác cần chú ý khi tính năng routing được bật, giờ trang default.aspx có thể được kích hoạt bở nhiều URL khác nhau, nên đường dẫn tương đối đến file silverlight.js và MyApp.xap sẽ không còn hợp lệ. Ví dụ bạn sẽ thấy các yêu cần đến http://www.hanselman.com/abrams/restaurant/25/plate/4/Silverlight.jshttp://www.hanselman.com/abrams/silverlight.js. Và điều này sẽ dẫn đến lỗi sau:

image

Line: 56
Error: Unhandled Error in Silverlight Application
Code: 2104
Category: InitializeError
Message: Could not download the Silverlight application. Check web server settings

Để xử lý trường hợp này, ta hãy sửa lại như sau:

  <script type="text/javascript" src='<%= this.ResolveUrl("~/Silverlight.js") %>'></script>

 <param name="source" value="<%= this.ResolveUrl("~/ClientBin/MyApp.xap") %>"/>

Giờ nếu chúng ta cho một địa chỉ bao gồm PlateID kiểu như sau:

http://localhost:30045/restaurant/48/plate/119#/Plates

image

Thì sẽ lấy về được từ mục kết quả đơn…

image

Bước 2: Cho phép các máy tìm kiếm biết về các liên kết của bạn bằng một Sitemap

Giờ ứng dụng của ta đã hỗ trợ các liên kết sâu và từng thành phần, với các mục dữ liệu đều có URL riêng. Nhưng làm sao một máy tìm kiếm có thể tìm thấy các URL đó? Tất nhiên chúng ta hi vọng mọi người sẽ nói về (và tạo liên kết đến) trang web của chúng ta trên các mạng xã hội, nhờ đó các máy tìm kiếm có thể lấy một số để tạo chỉ mục, nhưng ta cũng muốn có một giải pháp toàn diện hơn. Chúng ta muốn cung cấp cho máy tìm kiếm TẤT CẢ các liên kết có trong ứng dụng, và ta có thể làm được điều này với một sitemap.

Định dạng của một sitemap được chấp nhận bởi tất cả các máy tìm kiếm chính… bạn có thể tìm thêm thông tin tại http://sitemap.org.

Để biết cách chúng làm việc, hãy nhìn vào cách một máy tìm kiếm lập chỉ mục cho một site hướng dữ liệu như http://www.amazon.com. Khi một máy tìm kiếm lần đầu tiên truy cập vào một site, nó sẽ đọc file robots.txt ở thư mục gốc của site. Trong trường hợp này thì đó là http://www.amazon.com/robots.txt.

image

Trong ví dụ này, bạn có thể nhìn vào đầu file, có một danh sách các thư mục mà các máy tìm kiếm được yêu cầu bỏ qua. Còn ở cuối trang, có một danh sách các sitemap cho máy tìm kiếm có thể dùng để lập chỉ mục cho nội dung của site.

Ghi chú: bạn có thể dùng các công cụ được cung cấp bởi các máy tìm kiếm chính để đăng ký sitemap.

Nếu ta truy cập vào một trong các URL đó, bạn sẽ thấy một file sitemap, như được hiển thị dưới đây:

image

Trong trường hợp này, vì Amazon.com là một site khổng lồ, nên các link này thực sự lại được chỉ đến các sitemap khác (file này được gọi là file chỉ mục Sitemap). Tiếp tục duyệt theo các liên kết trên, ta có thể thấy được các liên kết đến các sản phẩm thực sự.

image

Bạn có thể thấy định dạng của chúng tương tự như sau:

<urlset xmlns="http://www.google.com/schemas/sitemap/0.84">
<url>
    <loc>http://www.amazon.com/GAITHER-COMMITTEE-EISENHOWER-COLD-WAR/dp/081425005X</loc>
</url>
<url>
    <loc>http://www.amazon.com/CONTROLLING-VICE-REGULATING-PROSTITUTION-CRIMINAL/dp/0814250076</loc>
</url>

Một điều thú vị và các liên kết đó được thay đổi khi các mục dữ liệu được thêm vào hay xóa bớt từ kho dữ liệu của Amazon.

Hãy xem qua cách ta có thể dùng để xây dựng một sitemap giống như vậy trên site của chúng ta.

Trong web project, ta hãy thêm vào một Search Sitemap dùng hộp thoại Add New Item trong Visual Studio.

image

Hãy chắc chắn là bạn đã cài đặt RIA Services Toolkit để có mục này.

Khi làm điều này, ta sẽ có một file robots.txt giống dưới đây:

# This file provides hints and instructions to search engine crawlers.
# For more information, see
http://www.robotstxt.org/.

# Allow all
User-agent: *

# Prevent crawlers from indexing static resources (images, XAPs, etc)
Disallow: /ClientBin/

# Register your sitemap(s) here.
Sitemap: /Sitemap.aspx

và một file sitemap.aspx.

Để có thêm thông tin, bạn có thể đọc: Uncovering web-based treasure with Sitemaps

Để xây dựng sitemap này, ta cần tạo tạo một view khác cho dữ liệu trong PlateViewDomainService. Trong trường hợp này chúng ta dùng nó trong file ASP.NET. Để làm điều này, ta sẽ dùng asp:DomainDataSource. Bạn có thể cấu hình nó trong trình thiết kế giống như sau:

Bằng cách kéo thả một Repeater và trong form, cái ta có được sẽ giống như sau:

image

sau đó nhấp phải chuột và cấu hình nguồn dữ liệu:

image

Chọn một DataSource mới:

image

image

image

Cuối cùng, ta kết thúc với hai tập liên kết trong sitemap:

  1: <asp:DomainDataSource runat="server" ID="RestaurauntSitemapDataSource"
  2:         DomainServiceTypeName="MyApp.Web.DishViewDomainService"
  3:         QueryName="GetRestaurants" />
  4:
  5: <asp:Repeater runat="server" id="repeater" DataSourceID="RestaurauntSitemapDataSource" >
  6:     <HeaderTemplate>
  7:         <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  8:     </HeaderTemplate>
  9:     <ItemTemplate>
 10:               <url>
 11:                  <loc><%= Request.Url.AbsoluteUri.ToLower().Replace("sitemap.aspx",string.Empty) + "restaurant/"%><%# HttpUtility.UrlEncode(Eval("ID").ToString()) %></loc>
 12:               </url>
 13:  </ItemTemplate>
 14: </asp:Repeater>
 15:
 16: <asp:DomainDataSource ID="PlatesSitemapDataSource" runat="server"
 17:     DomainServiceTypeName="MyApp.Web.DishViewDomainService"
 18:     QueryName="GetPlates">
 19: </asp:DomainDataSource>
 20:
 21: <asp:Repeater runat="server"  id="repeater2" DataSourceID="PlatesSitemapDataSource">
 22:     <ItemTemplate>
 23:             <url>
 24:                <loc><%= Request.Url.AbsoluteUri.ToLower().Replace("sitemap.aspx",string.Empty) + "restaurant/"%><%# HttpUtility.UrlEncode(Eval("RestaurantID").ToString()) + "/plate/" + HttpUtility.UrlEncode(Eval("ID").ToString()) %></loc>
 25:             </url>
 26:     </ItemTemplate>
 27:     <FooterTemplate>
 28:         </urlset>
 29:     </FooterTemplate>
 30: </asp:Repeater>
 31:

Như bạn có thể thấy ở dòng 3 và 20, ta đang gọi trực tiếp các phương thức GetRestaurant và GetPlates được định nghĩa trong DomainService.

Hiện tại thì với bất kỳ tập dữ liệu nào, dù là hợp lý thì việc truy cập trên cũng đòi hỏi rất nhiều tài nguyên hệ thống. Nguyên nhân là vì nó phải quét qua toàn bộ các dòng trong CSDL. Trong khi việc đảm bảo dữ liệu được cập nhật là cần thiết, ta cũng phải cân bằng với khả năng chịu tải của server. Một cách dễ dàng để làm điều này là dùng tính năng đệm lại dữ liệu trong vòng 1 giờ. Để có thêm thông tin, bạn có thể xem ASP.NET Caching: Techniques and Best Practices.

<%@ OutputCache Duration="3600" VaryByParam="None" %>

Một cách tiếp cận khác cho các tập dữ liệu lớn là chia nhỏ thành nhiều sitemap khác nhau như ví dụ về amazon.com mà ta đã xem ở trên.

image

Nếu ta lấy một trong các URL  trên và duyệt chúng, ta sẽ nhảy đến trang mong muốn.

image

Bước 3: Cung cấp một phiên bản chi tiết cho các nội dung quan trọng

Thật tuyệt vời, ta đã có các liên kết đến các trang, ta đã có cách cho phép các máy tìm kiếm duyệt đến các liên kết đó, nhưng chúng định tìm gì trên trang của bạn? Chà, các máy tìm kiếm chủ yếu diễn dịch các trang HTML, vậy nên nếu ta mở mã nguồn ra xem (Page\View Source), ta sẽ thấy những gì các máy tìm kiếm thấy:

image

Hay nếu ta duyệt với Silverlight bị disabled (Tools\Manage Addons), ta sẽ thấy như sau:

image

Một trang trắng trống rỗng!

Tất nhiên chẳng có nội dung động nào được hiển thị. Các mã chương trình thực sự phải được nạp và chạy, mà tôi đảm bảo rằng chẳng có máy tìm kiếm nào định chạy các mã Silverlight (hay flash hoặc ajax) của bạn tại các trung tâm dữ liệu. Vậy nên cái tôi cần là một số nội dung thay thế.

May mắn là điều này cũng khá đơn giản. Đầu tiên hãy tìm một nội dung để hiển thị. Một điều quan trọng phải nhắc đến là nội dung này không chỉ được hiển thị bởi máy tìm kiếm. Nội dung được viết riêng cho các máy tìm kiếm đôi khi được gọi là “lừa” máy tìm kiếm hay Web Spam khi nó làm cho các máy tìm kiếm hiểu sai nội dung của site. Thay vào đó, nội dung này sẽ được hiển thị thay thế nếu người dùng không cài đặt sẵn Silverlight. Nó không có đầy đủ tính năng, nhưng nó giúp mang lại trải nghiệm tốt hơn. Bản thân các phần mềm của các máy tìm kiếm cũng không hỗ trợ Silverlight, do vậy trong trường hợp này chúng vẫn có một số dữ liệu để lập chỉ mục.

Thêm đoạn HTML sau vào trang default.aspx:

   <div id="AlternativeContent" style="display: none;">
        <h2>Hi, this is my alternative content</h2>
   </div>

Chú ý display:none có nghĩa là ta không mong muốn nó được hiển thị… trừ khi Silverlight không được cài đặt. Để làm điều này, thêm đoạn lệnh sau và trang:

<script type="text/javascript">
     if (!isSilverlightInstalled()) {
            var obj = document.getElementById('AlternativeContent');
            obj.style.display = "";
        }
</script>

Ghi chú là phương thức isSilverlightInsalled được lấy từ một bài viết tuy cũ nhưng hay của Petr. Tôi đơn giản là thêm nó vào file Silverlight.js:

function isSilverlightInstalled() {
    var isSilverlightInstalled = false;
    try {
        //check on IE
        try {
            var slControl = new ActiveXObject('AgControl.AgControl');
            isSilverlightInstalled = true;
        }
        catch (e) {
            //either not installed or not IE. Check Firefox
            if (navigator.plugins["Silverlight Plug-In"]) {
                isSilverlightInstalled = true;
            }
        }
    }
    catch (e) {
        //we don't want to leak exceptions. However, you may
        //to add exception tracking code here
    }
    return isSilverlightInstalled;
}

Khi ta chạy từ một trình duyệt không có Silverlight, ta sẽ thấy nội dung thay thế:

image

Nhưng nếu với Silverlight được cài đặt sẵn, ta sẽ có nội dung Silverlight được hiển thị:

image

Thật tuyệt, nhưng làm sao ta xuất ra đúng nội dung?  Ta muốn hiển thị chính xác dữ liệu giống như trong ứng dụng Silverlight và ta muốn viết càng ít lệnh càng tốt. Ta thực sự không muốn duy trì nhiều trang. Vậy nên hãy thêm một số đoạn lệnh rất đơn giản vào phần div AlternativeContent. ListView này được dùng cho thông tin chi tiết về Restaurant.

<asp:ListView ID="RestaurnatDetails" runat="server"
                EnableViewState="false">
   <LayoutTemplate>
       <asp:PlaceHolder ID="ItemPlaceHolder" runat="server"/>
   </LayoutTemplate>
   <ItemTemplate>
       <asp:DynamicEntity ID="RestaurnatEntity" runat="server"/>
   </ItemTemplate>
</asp:ListView>

Giờ ta cần gắn nối vào nguồn dữ liệu… Tôi có thể làm điều này rất dễ dàng trong trình thiết kế của Visual Studio. Nhớ là bạn phải cho phần div được hiển thị lên (visible) để có thể làm việc với nó trong trình soạn thảo.

image

Sau đó ta cấu hình DataSource, rất đơn giản để có thể chọn phương thức cần dùng:

image

Tiếp theo ta gắn nối tham số cho phương thức truy vấn dựa trên cách phân cấp ta dùng.

image

Giờ làm giống hệt như trong ListView Plates…

Nó cho ta một đoạn lệnh aspx đơn giản:

  1:            <asp:ListView ID="RestaurnatDetails" runat="server"
  2:                         EnableViewState="false" DataSourceID="restaurantsDomainDataSource">
  3:                <LayoutTemplate>
  4:                      <asp:PlaceHolder ID="ItemPlaceHolder" runat="server"/>
  5:                </LayoutTemplate>
  6:                <ItemTemplate>
  7:                     <asp:DynamicEntity ID="RestaurnatEntity" runat="server"/>
  8:                </ItemTemplate>
  9:            </asp:ListView>
 10:
 11:            <asp:DomainDataSource ID="restaurantsDomainDataSource" runat="server"
 12:                               DomainServiceTypeName="MyApp.Web.DishViewDomainService"
 13:                               QueryName="GetRestaurant">
 14:               <QueryParameters>
 15:                  <asp:RouteParameter name="id" RouteKey="restaurantId"
 16:                                   DefaultValue ="-1" Type = "Int32"/>
 17:               </QueryParameters>
 18:            </asp:DomainDataSource>
 19:

Tiếp theo, ta muốn cho phép các control đó có thể tạo ra giao diện động dựa trên dữ liệu:

  1:         protected void Page_Init(object sender, EventArgs e)
  2:         {
  3:             RestaurnatDetails.EnableDynamicData(typeof(MyApp.Web.Restaurant));
  4:             PlateDetails.EnableDynamicData(typeof(MyApp.Web.Plate));
  5:             string resId = Page.RouteData.Values["restaurant"] as string;
  6:             if (resId != null) { Response.Write("<script type=text/javascript>window.location.hash='#/Plates';</script"+">"); }
  7:         }
  8:

Nhớ là ta đã thêm các dòng 4-5 để cho phép dữ liệu động trên 2 ListView này.

Bước cuối cùng là ta cần thêm tập các mẫu mà DynamicData dùng. Bạn có thể lấy nó từ bất kỳ dự án Dynamic Data nào, chỉ đơn giản copy vào trong thư mục gốc của dự án web.

image

Bạn có thể sửa các mẫu đó để kiểm soát chính xác cách dữ liệu được hiển thị.

Trong thư mục EntityTemplates, ta cần áp dụng mẫu cho mỗi thực thể (Plate và Restaurant  trong trường hợp này). Điều này sẽ kiểm soát cách chúng hiển thị.

  1: <%@ Control Language="C#" CodeBehind="Restaurant.ascx.cs" Inherits="MyApp.Web.RestaurantEntityTemplate" %>
  2:
  3:       <asp:DynamicControl  ID="DynamicControl8" runat="server" DataField="ImagePath" />
  4:       <ul class="restaurant">
  5:       <li>
  6:          <ul class="restaurantDetails">
  7:              <li><h2><asp:DynamicControl ID="NameControl" runat="server" DataField="Name" /> </h2> </li>
  8:              <li><asp:DynamicControl ID="DynamicControl1" runat="server" DataField="ContactName" /> (<asp:DynamicControl ID="DynamicControl2" runat="server" DataField="ContactTitle" />)</li>
  9:              <li><asp:DynamicControl ID="DynamicControl3" runat="server" DataField="Address" />  </li>
 10:              <li><asp:DynamicControl ID="DynamicControl4" runat="server" DataField="City" />, <asp:DynamicControl ID="DynamicControl5" runat="server" DataField="Region" />  <asp:DynamicControl ID="DynamicControl6" runat="server" DataField="PostalCode" />  </li>
 11:              <li><asp:DynamicControl ID="DynamicControl7" runat="server" DataField="Phone" />  </li>
 12:              <li><asp:HyperLink runat="server" ID="link"  NavigateUrl="<%#GetDetailsUrl() %>" Text="details.."></asp:HyperLink></li>
 13:          </ul>
 14:       </li>
 15:       </ul>
 16:

Chú ý ở đây, ta chi làm một số thao tác định dạng cơ bản và chỉ đưa ra các trường dữ liệu muốn hiển thị, làm tương tự cho Plate.

Giờ chúng ta đã sẵn sàng để chạy.

Nếu không truyền bất kỳ tham số nào, ta sẽ lấy được danh sách tất cả các nhà hàng, và tất nhiên là được hiển thị bằng mã HTML.

image

sau đó ta có thể thêm đường dẫn vào để chuyển đến một món trong một nhà hàng xác định.

image

Nhưng, đây là một trình duyệt thực sự, để đảm bảo ta biết nó được hiển thị đến một máy tìm kiếm thế nào, hãy thử qua Lynx. Lynx là trình duyệt đầu tiên tôi dùng từ năm 1992 trên máy DEC2100 tại phòng thí nghiệm Leazar ở North Carolina State University… và nó vẫn làm việc tốt cho tới tận ngày nay.

image

và thông tin chi tiết

image

Trình duyệt văn bản cổ điển này chỉ hiển thị các đoạn văn bản – là những gì các máy tìm kiếm nhìn thấy.

Giờ là một bài test thực sự.

Chúng ta sẽ dùng Bing cho “my foodie Explorer Cooking Class with Joe..”, và nó đây:

image

Nhấp chuột lên trên liên kết đó?

… nó sẽ chuyển bạn đến chính xác trang web mà bạn cần với nội dung Silverlight.

image

Tất nhiên nó cũng làm việc tốt với các trình duyệt tương tự khác…

Tổng kết

Những gì bạn đã xem là các bước cơ bản để tạo một ứng dụng web hướng dữ liệu với Silverlight và hỗ trợ SEO! Chúng ta đi qua ba bước:

  • Bước 1: Tạo các liên kết đến các nội dung bên trong.
  • Bước 2: Cho các máy tìm kiếm biết các các liên kết đó nhờ Sitemap.
  • Bước 3: Cung cấp một phiên bản “cấp thấp” cho các nội dung quan trong.
  • Gửi phản hồi

    Mời bạn điền thông tin vào ô dưới đây hoặc kích vào một biểu tượng để đăng nhập:

    WordPress.com Logo

    Bạn đang bình luận bằng tài khoản WordPress.com Log Out / Thay đổi )

    Twitter picture

    Bạn đang bình luận bằng tài khoản Twitter Log Out / Thay đổi )

    Facebook photo

    Bạn đang bình luận bằng tài khoản Facebook Log Out / Thay đổi )

    Google+ photo

    Bạn đang bình luận bằng tài khoản Google+ Log Out / Thay đổi )

    Connecting to %s