同一站點的不同域的 robots.txt 文件
我有一個可以從多個不同域訪問的 ASP.NET MVC 4 Web 應用程序。該站點根據請求中的域完全本地化(在概念上與此問題類似)。
我想包含一個 robots.txt 文件,並且我想根據域對 robots.txt 文件進行本地化,但我知道在站點的文件系統目錄中只能有一個物理“robots.txt”文本文件。
使用 ASP.NET MVC 框架在每個域的基礎上實現 robots.txt 文件的最簡單/最好的方法是什麼(甚至可能),以便同一個站點安裝為每個域提供內容,但內容機器人文件的本地化取決於請求的域?
這個過程相當簡單:
控制器/動作方法
使用你的路由表,將你的 robots.txt 路徑映射到控制器中的一個動作(我使用控制器和動作作為一個簡單的例子來幫助你開始),就像你對給定路徑的任何其他控制器和視圖一樣。
在操作中,檢查請求中的域並為該域選擇您的 robots.txt 內容。
使用以下內容從磁碟返回適當的文件:
ContentResult並將其設置ContentType為"text/plain"FilePathResult如果您的機器人文件只是磁碟上的文件,請通過Controller類中的一種輔助方法,例如File(name, "text/plain")以下範例假設有一個頂級 robots.txt 文件:
// In App_Start/RouteConfig: public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( name: "robots", url: "robots.txt", defaults: new { controller = "Seo", action = "Robots" } ); // The controller: public class SeoController : Controller { public ActionResult Robots() { var robotsFile = "~/robots-default.txt"; switch (Request.Url.Host.ToLower()) { case "stackoverflow.com": robotsFile = "~/robots-so.txt"; break; case "meta.stackoverflow.com": robotsFile = "~/robots-meta.txt"; break; } return File(robotsFile, "text/plain"); } }使其工作的最簡單方法之一是確保
runAllManagedModulesForAllRequests在 web.config 中使用的所有請求都呼叫路由模組(不要使用它,請參閱下一段):<system.webServer> <handlers> ... </handlers> <modules runAllManagedModulesForAllRequests="true" /> </system.webServer>這通常不是一件好事,因為現在所有靜態文件(css、js、txt)在被轉移到靜態文件處理程序之前都經過託管處理程序。IIS非常擅長快速提供靜態文件(一個主要是靜態文件的網站會在 CPU 之前最大限度地使用您的磁碟 I/O),因此為了避免這種性能損失,推薦的方法是下面的 web.config 範例部分。
ExtensionlessUrlHandler-Integrated-4.0請注意與 Visual Studio MVC 4 模板應用程序中的處理程序的相似之處:<system.webServer> <handlers> <add name="Robots-Integrated-4.0" path="/robots.txt" verb="GET" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" /> ... the original handlers ... </handlers> <modules runAllManagedModulesForAllRequests="false" /> </system.webServer>優點/缺點
一旦你開始使用這種方法,它的優點就會變得很明顯:
- 您可以使用幫助程序動態生成 robots.txt 文件以生成操作 url,然後您可以將其全部/部分添加到模板 robots.txt 文件中。
- 您可以檢查機器人使用者代理以針對每個機器人使用者代理返回不同的機器人文件
- 您可以使用相同的控制器為網路爬蟲輸出 sitemap.xml 文件
- 您可以從站點使用者可以輕鬆管理的數據庫表中管理機器人內容。
不利的一面是,
- 您的機器人文件現在使您的路線表複雜化,實際上並不需要
- 您將需要優化記憶體以防止持續的磁碟讀取。但是,這對於您採用的任何方法都是一樣的。
還要記住,不同的 robots.txt 文件可用於不同的子目錄。這對於路由和控制器方法變得很棘手,因此
IHttpHandler這種情況下的方法(如下)更容易。IHttpHandler 方法
您也可以使用
IHttpHandler在 web.config 中註冊的自定義來執行此操作。我強調自定義,因為這避免了讓所有控制器看到所有請求的需要(使用runAllManagedModulesForAllRequests="true",與將自定義路由處理程序添加到路由表中不同。這也可能是一種比控制器更輕量級的方法,但是您必須擁有巨大的站點流量才能注意到差異。它的另一個好處是一段可重用的程式碼,您可以將其用於所有站點。您還可以添加自定義配置部分來配置機器人使用者代理/域名/路徑映射到機器人文件。
<system.webServer> <handlers> <add name="Robots" verb="*" path="/robots.txt" type="MyProject.RobotsHandler, MyAssembly" preCondition="managedHandler"/> </handlers> <modules runAllManagedModulesForAllRequests="false" /> </system.webServer>public class RobotsHandler: IHttpHandler { public bool IsReusable { get { return false; } } public void ProcessRequest(HttpContext context) { string domain = context.Request.Url.Host; // set the response code, content type and appropriate robots file here // also think about handling caching, sending error codes etc. context.Response.StatusCode = 200; context.Response.ContentType = "text/plain"; // return the robots content context.Response.Write("my robots content"); } }子目錄中的 robots.txt
要為子目錄和站點根目錄服務機器人,您不能輕易使用控制器方法;在這種情況下,處理程序方法更簡單。這可以配置為將 robots.txt 文件請求提取到任何子目錄並相應地處理它們。然後,您可以選擇為某些目錄返回 404,或者為其他目錄返回 robots 文件的一個小節。
我在這里特別提到這一點,因為這種方法也可用於 sitemap.xml 文件,為站點的不同部分提供不同的站點地圖,相互引用的多個站點地圖等。
其他參考: