如何仅提取包含整个HTML页面的ajax响应的body标记内的内容?

时间:2010-11-23 22:06:46

标签: jquery html ajax

我有以下代码:

$.ajax(
        {
            url: rootPath + "Framework/GetPartial",
            data: { partialName: partialName },
            type: "POST",
            success: function (response)
            {
                $('#loading').hide();
                $('#partialContent').hide().html(response).fadeIn();
            },
            error: function (xhr, textStatus, errorThrown)
            {
                $('#loading').hide();
                $('#partialContent').hide().html('An error occurred. Details below:<br /><br />' + xhr.responseText).fadeIn();
            }
        });

我关心的是错误处理功能。当服务器上发生错误时,将发送html页面作为包含详细调试信息的响应。我想将此html响应加载到现有页面中,但在响应中包含<HTML><HEAD><BODY>标记会破坏整个页面的格式。如何在以下HTML响应中使用JQuery解析body标签中的内容?

<html>

    <head>

        <title>The method or operation is not implemented.</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}

         b {font-family:"Verdana";font-weight:bold;color:black;margin-top: -5px}

         H1 { font-family:"Verdana";font-weight:normal;font-size:18pt;color:red }

         H2 { font-family:"Verdana";font-weight:normal;font-size:14pt;color:maroon }

         pre {font-family:"Lucida Console";font-size: .9em}

         .marker {font-weight: bold; color: black;text-decoration: none;}

         .version {color: gray;}

         .error {margin-bottom: 10px;}

         .expandable { text-decoration:underline; font-weight:bold; color:navy; cursor:hand; }

        </style>

    </head>



    <body bgcolor="white">



            <span><H1>Server Error in '/AlexAndNikki' Application.<hr width=100% size=1 color=silver></H1>



            <h2> <i>The method or operation is not implemented.</i> </h2></span>



            <font face="Arial, Helvetica, Geneva, SunSans-Regular, sans-serif ">



            <b> Description: </b>An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.



            <br><br>



            <b> Exception Details: </b>System.NotImplementedException: The method or operation is not implemented.<br><br>



            <b>Source Error:</b> <br><br>



            <table width=100% bgcolor="#ffffcc">

               <tr>

                  <td>

                      <code><pre>



Line 19:         public PartialViewResult GetPartial(string partialName)

Line 20:         {

<font color=red>Line 21:             throw new NotImplementedException();

</font>Line 22:             //System.Threading.Thread.Sleep(3000);

Line 23:             if (!ViewExists(partialName))</pre></code>



                  </td>

               </tr>

            </table>



            <br>



            <b> Source File: </b> C:\Users\alex.ford\Documents\Visual Studio 2010\Projects\AlexAndNikki\AlexAndNikki\Controllers\FrameworkController.cs<b> &nbsp;&nbsp; Line: </b> 21

            <br><br>



            <b>Stack Trace:</b> <br><br>



            <table width=100% bgcolor="#ffffcc">

               <tr>

                  <td>

                      <code><pre>



[NotImplementedException: The method or operation is not implemented.]

   AlexAndNikki.Controllers.FrameworkController.GetPartial(String partialName) in C:\Users\alex.ford\Documents\Visual Studio 2010\Projects\AlexAndNikki\AlexAndNikki\Controllers\FrameworkController.cs:21

   lambda_method(Closure , ControllerBase , Object[] ) +127

   System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters) +258

   System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +39

   System.Web.Mvc.&lt;&gt;c__DisplayClassd.&lt;InvokeActionMethodWithFilters&gt;b__a() +125

   System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation) +640

   System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext controllerContext, IList`1 filters, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +312

   System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +709

   System.Web.Mvc.Controller.ExecuteCore() +162

   System.Web.Mvc.&lt;&gt;c__DisplayClass8.&lt;BeginProcessRequest&gt;b__4() +58

   System.Web.Mvc.Async.&lt;&gt;c__DisplayClass1.&lt;MakeVoidDelegate&gt;b__0() +20

   System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +453

   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean&amp; completedSynchronously) +371

</pre></code>



                  </td>

               </tr>

            </table>



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

<!-- 

[NotImplementedException]: The method or operation is not implemented.

   at AlexAndNikki.Controllers.FrameworkController.GetPartial(String partialName) in C:\Users\alex.ford\Documents\Visual Studio 2010\Projects\AlexAndNikki\AlexAndNikki\Controllers\FrameworkController.cs:line 21

   at lambda_method(Closure , ControllerBase , Object[] )

   at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters)

   at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters)

   at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClassd.<InvokeActionMethodWithFilters>b__a()

   at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation)

   at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext controllerContext, IList`1 filters, ActionDescriptor actionDescriptor, IDictionary`2 parameters)

   at System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName)

   at System.Web.Mvc.Controller.ExecuteCore()

   at System.Web.Mvc.MvcHandler.<>c__DisplayClass8.<BeginProcessRequest>b__4()

   at System.Web.Mvc.Async.AsyncResultWrapper.<>c__DisplayClass1.<MakeVoidDelegate>b__0()

   at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()

   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

-->

修改

是否有办法将响应字符串加载到iframe中?如果可能的话,这将是非常好的。

类似的东西:

$('#partialContent').html('<iframe>' + xhr.responseText + '</iframe>');

显然我尝试过这段代码并没有用,但也许有人知道如何让iframe解决问题?

4 个答案:

答案 0 :(得分:3)

你可以这样做:

$('#partialContent').hide().html($('body',response).contents()).fadeIn();

这是下面.empty().append()的快捷方式,但主要部分是$('body',response),它在响应中查找<body>元素,然后将其内容作为要追加的元素

答案 1 :(得分:2)

我再次解决了我自己的问题。这只是我的第二个问题,两次我只花了几个小时谷歌搜索并自己想出了答案。对不起大家!我真的很想接受别人的回答。

无论如何,我发现最简单的解决方案是将包含html的响应字符串动态加载到iframe中。这是一个例子:

error: function (xhr, textStatus, errorThrown)
            {
                $('#loading').hide();
                $('#partialContent').html('<iframe style="width: 100%; height: 500px; border: solid 1px #000000;" id="errorFrame"></iframe>');
                var myFrame = $('#errorFrame')[0]; //top.frames['errorFrame'];
                myFrame = myFrame.contentWindow || myFrame.contentDocument.document || myFrame.contentDocument;
                myFrame.document.open();
                myFrame.document.write(xhr.responseText);
                myFrame.document.close();
            }

如果您需要此解决方案,请记住您必须考虑到良好的IE并且未能遵循W3C标准。 contentWindow是IE等同于contentDocument。只要你包括myFrame = myFrame.contentWindow || myFrame.contentDocument.document || myFrame.contentDocument;,你就可以了。

以下是加载到iframe中的错误页面示例: http://67.2.141.90/AlexAndNikki/Framework/GenerateError

感谢所有人的帮助!

答案 2 :(得分:1)

var content = $('body')。html(); //为您提供身体内容

答案 3 :(得分:0)

浏览器以不同方式处理完整的HTML页面。你应该只返回你想要的内容。

如果不可能,这将在不同级别查找<body>,具体取决于浏览器剥离的标签。

var $response = $( response );

var $content = (( $response.children('body').length ) ? $response.children('body').contents() :
               ( $response.filter('body').length ) ? $response.filter('body').contents() :
               $response).not('style,title,script');

$('#partialContent').hide().html( $content ).fadeIn();

没有保证,但可能会有所帮助。


编辑:没有注意到您正在处理错误回调,并尝试连接HTML。我上面的回答将导致[object Object]连接。

使用上面的代码,但在将响应添加到partialContent时使用此代码。

var $response = $( response );

var $content = (( $response.children('body').length ) ? $response.children('body').contents() :
               ( $response.filter('body').length ) ? $response.filter('body').contents() :
               $response).not('style,title,script');

$('#partialContent').hide().html('An error occurred. Details below:<br /><br />' +  
                      $('<div>').append( $content ).html()).fadeIn();

编辑:添加了代码以删除<title><style><script>标记,因为某些浏览器还会为您提供<head>的内容