【问题标题】:How do I pass values from javascript (innerhtml) to asp.net codebehind without hidden input field?如何在没有隐藏输入字段的情况下将值从 javascript (innerhtml) 传递到 asp.net 代码隐藏?
【发布时间】:2013-01-20 21:54:19
【问题描述】:

我有一个 aspx 页面(主页),我使用 window.loaded 事件在按钮单击时填充另一个 aspx 页面(弹出)上的一些 div。代码如下:

mainpage.aspx 上的脚本

  <script type="text/javascript">

      window.callback = function (doc) {

          if (document.getElementById('GridView2') != null)
          {
              // Get Gridview HTML and wrap it with <table> tag
              var temp = document.getElementById('GridView2').innerHTML;
              var temp2 = "<table>" + temp + "</table>";

              doc.getElementById('foo').innerHTML = temp2; // this works fine
          }
          else
          {
              // GridView is missing, do nothing!
          }
      }

      function openWindow() {

          // Only open a new Compose Email window if there is a Gridview present
          if ((document.getElementById('GridView2') != null)) {
              var mywindow = window.open("Popup.aspx");
          }
          else {
              alert("Please create GridView first");
          }
      }

Popup.aspx 上的代码

    <script type="text/javascript">
    function loaded() {
        window.opener.callback(document);
        alert(document.getElementById('foo').innerHTML); //This alerts the code I need

        //var input = document.createElement("input");
        //input.setAttribute("type", "hidden");
        //input.setAttribute("name", "testinput");
        //input.setAttribute("runat", "server");
        //input.setAttribute("value", document.getElementById('foo').innerHTML);

        ////append to form element that you want .
        //document.getElementById("foo2").appendChild(input);
    }
</script>

<asp:Button OnClick="Send_Email_Button_Click" ID="SendEmail" Text="Send Email" CssClass="Button1" runat="server" />
            <div id="foo" runat="server">

            </div>

Popup.aspx.cs

protected void Send_Email_Button_Click(object sender, EventArgs e)
{
    string subject = String.Format("TEST EMAIL");
    string mailto = "me@mysite.com";
    string mailfrom = Environment.UserName + "@mysite.com";
    string mailBody = "<h1>Testing</h1>";

    MailMessage mail = new MailMessage(mailfrom, mailto, subject, null);
    mail.IsBodyHtml = true;
    mail.Body = mailBody;
    SmtpClient smtpClient = new SmtpClient("smtphost");
    smtpClient.Credentials = CredentialCache.DefaultNetworkCredentials;
    try
    {
        smtpClient.Send(mail);
    }
    catch (Exception ex)
    {

    }
}

现在,我一直在尝试将 div.innerhtml 的值传递给代码隐藏,因此我可以使用此 HTML 标记创建电子邮件。我尝试使用隐藏的 div,但我得到了一个关于请求验证的 asp.net 错误:输入字段中的 html 代码,这是一个公平的观点。我似乎无法访问 div.InnerHtml。我得到值“\r\n\r\n”。我有我需要的值,但它是用 Javascript 编写的,我只需要一种方法将这个值传递给 C#,这样我就可以发送电子邮件了。

当我单击 SendEmail 按钮时,我再次收到警报(因为正在调用 window.loaded)。如何使 Popup.aspx 仅填充一次,而不是在每次单击按钮时填充?以及如何传递 innerhtml 值以使 SendEmail 工作?非常感谢您的关注。

【问题讨论】:

  • 除非您在页面声明中关闭页面上的请求验证,否则如果不清理您的 html,我认为这是不可能的。
  • 我想我会尝试将 HTML 的编码版本作为 POST 参数发送,看看是否可行

标签: javascript asp.net callback hidden-field mailmessage


【解决方案1】:

要向后面的代码发送一些数据,有两种方法。 发布获取

一种是通过回传发送数据 - 这意味着您需要将它们添加到隐藏或其他输入控件中,以便通过帖子发送它们。

另一种是将它们作为参数添加到url中。

这两种方法都可以与 ajax 调用一起使用。所以选择一个并将您的数据发送到后面的代码。

关于消息:

Request Validation: html code in an input field

这是一般用途的安全措施,在您的情况下,如果您知道您将在代码后面发送 html 代码,并且您知道如何控制它,只需禁用它并且不用担心 - 请小心您的操作稍后渲染。

来自 MSDN Request Validation in ASP.NET:

如果您希望您的应用程序接受 HTML,这可能是个问题 标记。例如,如果您的网站允许用户添加 cmets,您可以 希望让用户使用 HTML 标签执行基本格式设置 粗体或斜体文本。 在这种情况下,您可以禁用请求 手动验证和检查恶意内容,或者您可以 自定义请求验证,以便某些类型的标记或脚本 被接受

更新

有效的示例代码: 主页

<head runat="server">
    <title></title>

    <script type="text/javascript">
      window.callback = function (doc) {
            doc.getElementById('SendBack').value = escape("<b>send me back</b>"); 
      }

      function openWindow() {
            var mywindow = window.open("Page2PopUp.aspx");          
      }
    </script>

</head>
<body>
    <form id="form1" runat="server">
        <a href="#" onclick="openWindow();return false">open pop up</a>
    </form>
</body>
</html>

弹出页面

<head runat="server">
    <title></title>
   <script type="text/javascript">
    function GetDataBack() {
        window.opener.callback(document);
    }
</script>
</head>
<body >
    <form id="form1" runat="server">
    <div>
        <input id="SendBack" name="SendBack" value="" type="hidden" />    
        <asp:Button ID="Button1" runat="server" onclick="Button1_Click" Text="Button" OnClientClick="GetDataBack()" />    
        <asp:Literal runat="server" ID="txtDebugCode"></asp:Literal>    
    </div>
    </form>
</body>
</html>

并阅读它:

protected void Button1_Click(object sender, EventArgs e)
{
    txtDebugCode.Text = Server.UrlDecode(Request.Form["SendBack"]);
}

【讨论】:

  • 我怀疑请求验证可能会被“愚弄”。例如,使用 JSON 编码数据并将&lt; 替换为\u003c。如果这是在 inside JSON 字符串中完成的,那么 JSON 解码器会很好地将其转换回来.. 更好吗?好吧,至少它可能不需要全局停用“验证”。
  • @pst 实际上,如果在后面的代码中获取数据后,在页面上再次呈现它们,数据可能是危险的(注入代码)。因此,您必须小心避免这种情况 - 而不是在您将它们送回时。另一方面,当您将它们添加到输入控件时,您需要使用 javascript 对它们进行 html 编码 - 否则您可能会破坏回发数据。
  • 再多的验证也无法真正防止不安全的编码。不应将任意原始文本写入 HTML,就像不应跳过 SQL 中的占位符一样。有一些工具/方法可以在上下文中安全地使用数据。在这种情况下,HtmlEncode 可能会引起您的兴趣..
  • 我把 ValidateRequest="false" 放在两个页面的顶部,我仍然看到错误:“从客户端检测到潜在危险的 Request.Form 值(testinput="
  • @Freakishly 正确的是validateRequest="false"(第一个小写)。
【解决方案2】:

因此,经过半天的努力,我终于通过仅使用代码隐藏来处理客户端服务器脚本。我从未听说过 Server.Transfer 和 Page.PreviousPage,所以它对我很有帮助,但事实证明这正是我所需要的。

There is an excellent msdn article here 详细解释了这个概念,但如果您使用 Server.Transfer 打开新页面,您可以访问上一页的控件就足够了。现在我认为我的麻烦到此为止了,但显然 Server.Transfer 是古老的,并且与 UpdatePanel 处理回发的方式相混淆。 Another brilliant article explaining problems and workarounds is here。我使用msdn article on PostBackTrigger 终于让我的代码工作了。

最后,Aristos 的疯狂道具,他坐下来帮我解决了这个问题,所以我要把他的答案标记为正确答案——因为我的答案是替代方案,而不是我问题的答案。就是这样,伙计们!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多