404 página que muestra la página solicitada
-
02-07-2019 - |
Pregunta
Recientemente migré un sitio web a un nuevo CMS (Umbraco). Muchos de los enlaces han cambiado, pero se pueden corregir fácilmente buscando patrones en la URL, por lo que me gustaría escribir algo que redirija a la página correcta si no se encuentra el anterior. Esa parte no es un problema.
¿Cómo puedo obtener la URL solicitada después de que el navegador sea redirigido a mi página 404 personalizada? Intenté usar:
request.ServerVariables("HTTP_REFERER") 'sorry i corrected the typo from system to server.
Pero eso no funcionó.
¿Alguna idea?
El sitio está en IIS 6.0. Consideramos el uso de redireccionamientos 301, pero no tenemos forma de saber qué páginas han marcado las personas y hay unos cientos de páginas, por lo que a nadie le gusta gastar el tiempo para crear los 301.
Solución
Hago básicamente lo mismo que pides en una página personalizada de manejo de errores 404. En IIS 6, la URL original está en la cadena de consulta. El siguiente código muestra cómo obtener la URL original y luego reenviar al usuario. En mi caso, cambié de ASP antiguo a ASP.NET nuevo, por lo que todas las páginas .asp tuvieron que reenviarse a páginas .aspx. Además, algunas URL cambiaron, así que busco palabras clave en la URL anterior y reenvío.
//did the error go to a .ASP page? If so, append x (for .aspx) and
//issue a 301 permanently moved
//when we get an error, the querystring will be "404;<complete original URL>"
string targetPage = Request.RawUrl.Substring(Request.FilePath.Length);
if((null == targetPage) || (targetPage.Length == 0))
targetPage = "[home page]";
else
{
//find the original URL
if(targetPage[0] == '?')
{
if(-1 != targetPage.IndexOf("?aspxerrorpath="))
targetPage = targetPage.Substring(15); // ?aspxerrorpath=
else
targetPage = targetPage.Substring(5); // ?404;
}
else
{
if(-1 != targetPage.IndexOf("errorpath="))
targetPage = targetPage.Substring(14); // aspxerrorpath=
else
targetPage = targetPage.Substring(4); // 404;
}
}
string upperTarget = targetPage.ToUpper();
if((-1 == upperTarget.IndexOf(".ASPX")) && (-1 != upperTarget.IndexOf(".ASP")))
{
//this is a request for an .ASP page - permanently redirect to .aspx
targetPage = upperTarget.Replace(".ASP", ".ASPX");
//issue 301 redirect
Response.Status = "301 Moved Permanently";
Response.AddHeader("Location",targetPage);
Response.End();
}
if(-1 != upperTarget.IndexOf("ORDER"))
{
//going to old order page -- forward to new page
Response.Redirect(WebRoot + "/order.aspx");
Response.End();
}
Otros consejos
¿Qué tal:
Request.ServerVariables("HTTP_REFERER");
Muchos de los enlaces han cambiado, pero se pueden corregir fácilmente buscando patrones en la URL
En lugar de enviar a sus usuarios a un 404, ¿ha considerado usar reescrituras de URL? De esta forma, sus usuarios (y motores de búsqueda, si eso es importante para usted en este caso) obtendrán un 301 o 302 en lugar de tener que pasar por su controlador 404. Por lo general, es más rápido y menos estresante en sus servidores manejar la reescritura a nivel de URL que activar su código y procesarlo allí.
Microsoft ha lanzado un Módulo de reescritura de URL para IIS 7 , y hay una introducción decente aquí y aquí .
Para IIS 6, hay un buena introducción aquí para que la reescritura de URL funcione con ella, un poco diferente a IIS7.
Un ejemplo de regla de reescritura sería
# $1 will contain the contents of (.*) - everything after new-dir/
RewriteRule /new-dir/(.*) /find_old_page.asp?code=$1
hay unos cientos de páginas, por lo que a nadie le gusta gastar el tiempo para crear los 301
La belleza de las reglas de reescritura es que no necesita hacer una lista para enumerar explícitamente todas sus páginas, sino que puede escribir reglas que sigan el mismo patrón. Tuvimos que hacer algo similar a esto recientemente, y es sorprendente cuántas de las URL movidas podrían manejarse con un par de reglas simples.
En lugar de usar una página 404, creo que lo correcto sería redirigir con un 301 - Movido permanentemente código.
Esto es lo que hacemos en init en nuestras páginas 404:
Dim AttemptedUrl As String = Request.QueryString("aspxerrorpath")
If Len(AttemptedUrl) = 0 Then AttemptedUrl = Request.Url.Query
AttemptedUrl = LCase(AttemptedUrl)
CheckForRedirects(AttemptedUrl)
CheckforRedirects tiene una lógica personalizada para hacer coincidir las URL antiguas con las nuevas.
Yo diría que este es el enfoque preferido (a diferencia de los 301 o la reescritura de URL) si tiene suficiente información internamente para hacer coincidir una gran cantidad de URL del sistema antiguo con el nuevo sistema, p. ej. si tiene una tabla que hace coincidir las ID antiguas con las nuevas ID o algo similar.
Si hay un patrón consistente que puede usar para asignar URL antiguas a nuevas URL con una expresión regular, entonces, la reescritura de URL sería el camino a seguir.
Para construir sobre la sugerencia de reescrituras, Umbraco ya usa UrlRewriting.NET y se pueden agregar nuevas reescrituras a
\config\UrlRewriting.config
Espero que esto ayude
Actualización, en realidad desea recoger:
VB.NET:
Request.QueryString("aspxerrorpath")
C #:
Request.QueryString["aspxerrorpath"];