2010-05-18 4 views
6

J'ai un problème stupide. Une demande jQuery.ajax me renvoie un texte HTML complet sous la forme d'une chaîne. Je reçois une telle réponse en cas d'erreur sur le serveur. Le serveur me donne une description d'erreur que je veux placer à l'intérieur de l'endroit correspondant de ma page actuelle. Donc maintenant la question: J'ai une chaîne contient le document HTML complet (qui n'est pas un XML !!! voir <hr> élément à l'intérieur). Je n'ai besoin par exemple que d'une partie BODY en tant qu'objet jQuery. Ensuite, je pourrais l'ajouter à la partie correspondante de ma page.Comment obtenir <body> élément du html que l'on a comme une chaîne

Voici un exemple de la chaîne que je dois analyser:

<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) 
--> 

Répondre

13

Et le must-have réponse non jQuery:

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

Ceci renvoie ce qui est à l'intérieur des balises body.

MISE À JOUR accepte les attributs ce définis sur l'étiquette du corps

+0

Merci pour le conseil, mais je reçois seulement l'exception dans la première et la dernière version de cette expression – Oleg

+0

Regardez de plus près la balise 'body' de la chaîne de réponse. Votre motif ne correspond pas à l'étiquette d'ouverture. – user113716

+0

Merci, il a été corrigé. –

1

En cas d'erreur, vous pouvez passer toute la chaîne HTML à jQuery pour construire une représentation interne:

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

ou

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

ce fut ma première idée aussi, mais $ (entirePageHTML) .Find (« corps ») retourne un objet vide et jQuery (entirePageHTML) $ .Find ('body') .html() renvoie null. – Oleg

4

Une autre façon de faire, sans 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 vous avez besoin des attributs de la balise BODY, analysez-les également.

+0

Merci pour vos conseils. L'idée est bonne, mais 'bodyTags [0] .length' et' bodyTags [1] .length' ne peuvent pas être utilisés dans 'str.slice'. Ils produisent une mauvaise sous-chaîne. 'bodyTags.lastIndex' est OK comme dernier paramètre de' str.slice', mais je n'ai pas encore trouvé la bonne valeur pour le premier. – Oleg

+0

OK! data.responseText.slice (str.indexOf (bodyTags [0]), bodyTags.lastIndex) fonctionne! – Oleg

+0

@Oleg: Heureux que cela fonctionne pour vous, mais il me semble que str.indexOf (bodyTags [0]) retournerait simplement 0. Donc, ne seriez-vous pas le contenu *, y compris * l'étiquette ouverte ? Je pensais que tu ne voulais pas ça. – Robusto

Questions connexes