使用MVC3,如何让浏览器将传输的脚本明确地解释为HTML?

时间:2012-04-23 21:46:10

标签: asp.net-mvc-3 c#-4.0 html-parsing response.contenttype

在我的MVC应用程序中,我正在返回一些Javascript。但是,我在视图上使用防伪标记,因此渲染结果将是

<input name="__RequestVerificationToken" type="hidden" value="E8as+4Ff1u/c/+kuFcNXXCREB5pz5GAfH2krN5RvzURJaHZSApuRc4czZqmoITaKdy0XhN5sFfRzl4ne+wB3PkWOscBWzoIxUk3hGaFwDxRXSbMs8K9IwojEAtV5u57MR7hiSujr6MOTpjjbf5FPaYgO4gmH6lSR9mbSyO2IedI=" />

<script type="text/javascript">
   // Here, we ensure that jQuery is loaded then load up the rest of our JS in in order.
   ord = Math.random() * 10000000000000000;
   ...

所以有一些HTML要添加到页面然后是JS。

问题是我在Chrome中收到以下通知:

  

资源解释为脚本但使用MIME类型

传输

我需要浏览器将其解释为HTML才能使用防伪标记。

我试过把它放在视图上:

<%@Page Title="" Language="C#" ContentType="text/xml" %>

呈现:

<%System.Web.WebPages.DynamicPageDataDictionary`1[System.Object] Title="" Language="C#" ContentType="text/xml" %>

<input name="__RequestVerificationToken" type="hidden" 
...

...但同样的信息仍然存在。

在我的控制器中,我也尝试过:

        System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
        Byte[] bytes = encoding.GetBytes(page.clientScript);

        return new ContentResult
        {
            ContentType = "text/xml", // also tried text/html
            Content = Encoding.UTF8.GetString(bytes),
            ContentEncoding = System.Text.Encoding.UTF8
        }; 

同样的问题。

- 更新 -

这就是我调用MVC应用程序返回文本的方式:

  // used to load scripts on to the client script using a non-blocking asynch request
  (function() {
  function async_load(){
  var s = document.createElement('script');
  s.type = 'text/javascript';
  s.async = true;
  s.src = 'http://myserver/MyAppPath/someids';
  var x = document.getElementsByTagName('script')[0];
  x.parentNode.insertBefore(s, x);
  }
  if (window.attachEvent)
  window.attachEvent('onload', async_load);
  else
  window.addEventListener('load', async_load, false);
  })();

2 个答案:

答案 0 :(得分:0)

如果我理解正确,您需要一个MVC操作,它返回html和脚本标记,可以通过<script... include在页面中注入。您还希望通过MVC视图呈现此内容。

您错过的最大问题是,为了将此内容放入调用页面,您需要从脚本执行document.write - 您不能只发回HTML和脚本以响应脚本包括 - 浏览器不会理解它,它只期待javascript。

有几种方法可以做到这一点 - 我编写了一整套ViewContent MVC控制器方法,具有与View相同的重载,它将视图的结果返回给控制器操作一个字符串。然后,我可以将其作为字符串文字(对于html电子邮件生成很有用)传递回来,也可以传递给javascript编码器。

在这种情况下,你不需要如此通才。我们可以利用Darin Dimitrov对此SO的回答:Embed MVC Partial View into a document.write JS call并将您的视图分为视图和部分视图。视图写入document.write()骨架,部分视图呈现要注入页面的动态html。目前还不清楚你是否在主视图中使用Anti Forgery Token来调用脚本(在这种情况下它应该呈现为它返回的视图的一部分),或者你是否真的在脚本中对它进行硬编码。绝对不应该使用第二个,但我正在写这个答案,好像它是,因为这似乎是你想要的。

首先,您的部分视图(我们称之为Fragment.cshtml,将其放入~/Views/Shared

<input name="__RequestVerificationToken" 
type="hidden"value="[ommitted]" /> 

<script type="text/javascript"> 
// Here, we ensure that jQuery is loaded then load up the rest of our JS in in order. 
ord = Math.random() * 10000000000000000; 
...

其次,主持人视图名为SomeIds.cshtml

 @{ Response.ContentType = "text/javascript"; }
 document.write('@Html.Raw(HttpUtility.JavaScriptStringEncode(Html.Partial("~/Views/Shared/Fragment").ToHtmlString()))') 

现在,此视图返回document.write调用,该调用将Fragment.cshtml返回的HTML注入包含该脚本的页面。

答案 1 :(得分:0)

您是否正在返回已呈现所有标记的PartialView?

使用您的(表单和脚本包含)并在Controller中创建一个PartialView:

    public ActionResult Index(Models.MyModel model) 
    {
        // validate the model if needed
        return PartialView("[My PartialView Name]", model);
    }

您可以将脚本放在单独的文件中,并在PartialView中添加[script src]标记。