2010-05-18 7 views
6

Tengo un problema estúpido. Una solicitud jQuery.ajax me devuelve un texto HTML completo como una cadena. Recibo dicha respuesta en un caso de error en el servidor. El servidor me da una descripción del error que quiero colocar dentro del lugar correspondiente de mi página actual.Cómo obtener <body> elemento del html que uno tiene como una cadena

Así que ahora la pregunta: Tengo una cadena que contiene el documento HTML completo (que no es un elemento XML, vea el elemento <hr> en el interior). Necesito tener, por ejemplo, solo la parte BODY como un objeto jQuery. Entonces podría adjuntarlo a la parte correspondiente de mi página.

Aquí es un ejemplo de la cadena de la que tengo que analizar:

<html> 
    <head> 
    <title>The resource cannot be found.</title> 
    <style> 
     body {font-family:"Verdana";font-weight:normal;font-size: .7em;color:black;} 
     p {font-family:"Verdana";font-weight:normal;color:black;margin-top: -5px} 
     // ... 
    </style> 
    </head> 

    <body bgcolor="white"> 
    <span><H1>Server Error in '/' Application.<hr width=100% size=1 color=silver></H1> 
      <h2> <i>The resource cannot be found.</i> </h2></span> 
    <font face="Arial, Helvetica, Geneva, SunSans-Regular, sans-serif "> 

     <b> Description: </b>HTTP 404. The resource you are looking for ...bla bla.... 
     <br><br> 

     <b> Requested URL: </b>/ImportBPImagesInfos/Repository.svc/GetFullProfilimageSw<br><br> 

     <hr width=100% size=1 color=silver> 

     <b>Version Information:</b>&nbsp;Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.1 

    </font> 

    </body> 
</html> 
<!-- 
[HttpException]: A public action method &#39;.... 
    at System.Web.Mvc.Controller.HandleUnknownAction(String actionName) 
    at System.Web.Mvc.Controller.ExecuteCore() 
    at System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) 
    at System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext requestContext) 
    at System.Web.Mvc.MvcHandler.<>c__DisplayClass8.<BeginProcessRequest>b__4() 
    at System.Web.Mvc.Async.AsyncResultWrapper.<>c__DisplayClass1.<MakeVoidDelegate>b__0() 
    at System.Web.Mvc.Async.AsyncResultWrapper.<>c__DisplayClass8`1.<BeginSynchronous>b__7(IAsyncResult _) 
    at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`1.End() 
    at System.Web.Mvc.Async.AsyncResultWrapper.End[TResult](IAsyncResult asyncResult, Object tag) 
    at System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) 
    at System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) 
    at System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) 
    at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() 
    at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) 
--> 

Respuesta

13

Y la respuesta no jQuery imprescindible:

var bodyHtml = /<body.*?>([\s\S]*)<\/body>/.exec(entirePageHTML)[1]; 

Esto devolverá sólo cuál es el interior de las etiquetas del cuerpo.

ACTUALIZACIÓN este acepta los atributos establecidos en la etiqueta del cuerpo

+0

Gracias por el consejo, pero recibo solo una excepción en la primera y en la última versión de esta expresión – Oleg

+0

Mire más de cerca la etiqueta 'body' de la cadena de respuestas. Su patrón no coincidirá con la etiqueta de apertura. – user113716

+0

Gracias, se ha corregido. –

1

En caso de error, que podría pasar toda la cadena HTML para jQuery para construir una representación interna de la misma:

var bodyHtml = $(entirePageHTML).find('body').html(); 

o

var errorMessage = $(entirePageHTML).find('body h1').text(); 
+1

que era mi primera idea también, pero $ (entirePageHTML) .find ('cuerpo') devuelve un objeto jQuery vacía y $ (entirePageHTML) .find ('cuerpo'). html() devuelve nulo. – Oleg

4

Otra manera de hacer esto, sin jQuery:

function getStupidErrorMessage(str) { 
    var bodyTags = str.match(/<\/*body[^>]*>/gim); 
    // returns an array 
    // bodyTags[0] is body open, bodyTags[1] is body close 
    // unless someone output the markup backwards :) 
    bodyContents = str.slice(bodyTags[0].length,-(bodyTags[1].length)); 
    return bodyContents; // use as innerHTML of <body> 
} 

Si necesita los atributos de la etiqueta BODY, también los analiza.

+0

Gracias por el asesoramiento. La idea es buena, pero 'bodyTags [0] .length' y' bodyTags [1] .length' no se pueden usar en 'str.slice'. Producen una subcadena incorrecta. 'bodyTags.lastIndex' está bien como el último parámetro de' str.slice', pero aún no encontré el valor correcto para el primero. – Oleg

+0

¡Bien! data.responseText.slice (str.indexOf (bodyTags [0]), bodyTags.lastIndex) funciona! – Oleg

+0

@Oleg: me alegro de que funcione para usted, pero me parece que str.indexOf (bodyTags [0]) simplemente devolvería 0. ¿Entonces no estaría recibiendo los contenidos * incluyendo * la etiqueta abierta? Pensé que no querías eso. – Robusto

Cuestiones relacionadas