【问题标题】:Why do I have to encode a string when reading and writing form inputs using jquery?为什么在使用 jquery 读取和写入表单输入时必须对字符串进行编码?
【发布时间】:2017-02-05 19:09:21
【问题描述】:

我正在使用标准 Jquery 以编程方式从文本输入中读取数据,如下所示:

  var listName = $('#list').val();

然后我在提交之前将隐藏的输入字段添加到表单中:

var myForm = $("#myForm);
myForm.append('<input type="hidden" name="List" value="' + listName + '" />');

在一个示例中,字段中的值为:

Key Date & Times

所以在 UI 上看起来像这样

<input type="hidden" name="MyList" value="Key Date & Times" />

当我使用以下方式提交表单时:

var myForm = $("#myForm);
myForm.submit();

并在我只看到的 asp.net-mvc 服务器端检查它:

Key Date 

被发送过来。经过一番研究,建议编写一些javascript来运行该值:

encodeURIComponent()

在这样做并查看服务器端之后,我现在看到:

Key%20Date%20%26%20Times

如何将其转换回

Key Date & Times

在 C# asp.net-mvc 服务器端?或者另外,如果我在客户端做错了什么,如果您有任何建议,请告诉我。

我的主要问题是为什么我必须担心在表单中编码隐藏输入框的值。我原以为这会为你处理好。

【问题讨论】:

  • 很可能你在客户端做错了什么......但你没有显示任何代码。
  • 我不确定要显示什么其他代码。我有一个带有上面隐藏输入的表单,我可以通过 jquery 调用 Form.Submit。您认为还有哪些其他代码在这里会有所帮助?
  • 如果你正在做一个普通的 http post 表单提交,我认为你不需要做任何具体的事情来解决这个问题。它应该工作!您是否在劫持表单提交事件并发出 ajax GET 请求?
  • @Shyju - 我只是在打电话: $("myForm").submit();来自 jquery(没有 ajax)。我正在做的唯一不是普通的事情是从文本框中读取一个值,然后在调用表单提交之前以编程方式将该值放入隐藏的输入中((
  • 我不能再重复这种行为了。

标签: c# jquery asp.net-mvc forms encoding


【解决方案1】:
string decodeString = HttpUtility.UrlDecode(@"Key%20Date%20%26%20Times");

使用HttpUtility类的UrlDecode方法。

【讨论】:

  • 注意: using System.Web 是必需的。
【解决方案2】:

客户端出了点问题。我已经测试了以下代码,它与您编写的代码相似并且运行良好

<input type="hidden" id="ref" value="Key Date & Times" />
<form id="form1" action="~/home/handle" method="post">
    <input type="submit" />
</form>

<script>
    var myForm = $('#form1');
    var listName = $('#ref').val();
    myForm.append('<input type="hidden" name="name" value="' + listName + '" />');
</script>

您无需使用转换工具!

【讨论】:

  • @leora 我完全改变了我的答案。
【解决方案3】:

我认为不需要对你的代码做任何事情,它可以正常工作,我有以下代码,请确认。

视图/Html:

@using (@Html.BeginForm("Save", "Home", FormMethod.Post, new { id = "myForm", name = "myForm" }))
{
    <input type="button" class="btn btn-danger" value="Click" id="btnClick">
}

Jquery:

$(document).ready(function () {
    var myForm = $("#myForm");
    myForm.append('<input type="hidden" name="List" value="Key Date & Times" />');

    $('#btnClick').click(function () {
        var myForm = $("#myForm");
        myForm.submit();

    });
});

控制器:

public ActionResult Save()
{
      return RedirectToAction("Index");
}

输出:

【讨论】:

  • 使用Request["List"]string List 作为动作参数没有区别!如果她无法从动作参数中获得正确的List 值,她将无法获得它。
【解决方案4】:

当您使用 GET 方法提交表单时会发生这种情况(在 GET 方法中,'&' 充当变量分隔符)您必须使用 POST 方法或字符串操作。

如果您使用的是encodeURIComponent(),您可以在服务器端使用Server.UrlDecode(""); 将其转换回来

您也可以阅读本文以获取更多知识Click here

【讨论】:

    【解决方案5】:

    很可能您正在向服务器提交 GET 请求,因此每个输入表单字段的所有值都会在查询字符串中发布到服务器。

    这样,正如Zulqarnain Jalil 已经说过的那样,每个'&'都被服务器解释为查询字符串中键/值对的分隔符,因此您错过了“列表”的最后一部分" 隐藏的输入表单域。

    因此,在这种情况下,您必须使用“&”字符对所有值进行 url 编码。

    相反,如果您向服务器提交 POST 请求,则无需对表单字段值进行任何 url 编码,因为它们是单独传递给服务器的,即不在同一个字符串中。

    如果您想避免 url 编码,请尝试在 POST 请求中转换您的请求:

    var myForm = $("#myForm");
    myForm.method = "post";
    myForm.submit();
    

    【讨论】:

      【解决方案6】:

      你也可以使用。 var myForm = $("#myForm");有错字

      string decodeString = Server.UrlDecode("Key%20Date%20%26%20Times");
      

      string decodeString = Uri.UnescapeDataString("Key%20Date%20%26%20Times");
      

      【讨论】:

        【解决方案7】:

        这在很大程度上与实施针对跨站点脚本攻击 (XSS) 的安全性有关。您需要对将在发布请求中使用的所有 html 输入字段进行编码。否则,有人可以将 domaliciousStuff() 添加到文本字段中,并将其存储在数据库中。然后当数据再次显示在表单上时,您的脚本(现在保存在数据库中,将在网页上运行!)。

        AntiXSS 是一个很棒的库,它拥有比内置 Html.Encode 更多的功能。您可以通过 Nuget 包管理器找到它。

        https://www.nuget.org/packages/AntiXSS/

        【讨论】:

          【解决方案8】:

          您的主要问题在表单中编码隐藏输入框的值可以这样回答,这与它与任何数据相关的隐藏输入无关正在发布到服务器

          在您的情况下,当数据包含空格和 (&) 等特殊字符时,应用程序开发人员有责任对其进行编码,以便服务器可以安全地处理数据。包含空格和特殊字符会带来 XSS 等安全问题。这只是负责任的开发人员为减轻此类安全威胁应采取的众多步骤之一。

          关于如何在服务器端取回值,请使用 System.Web 命名空间中的以下类

          string values = "Key%20Date%20%26%20Times";
          string decodeString = HttpUtility.UrlDecode(values);
          

          希望它能回答你的问题

          【讨论】:

            【解决方案9】:

            您只需在表单标签中添加accept-charset="ISO-8859-1",不用担心编码它会自动转换特殊字符。

            <!DOCTYPE html>
            <html>
            <body>
            
            <form action="demo_form.asp" accept-charset="ISO-8859-1">
              First name: <input type="text" name="fname"><br>
              Last name: <input type="text" name="lname"><br>
              <input type="submit" value="Submit">
            </form>
            
            </body>
            </html>
            

            你可以测试一下here

            【讨论】:

            • 我看不出有什么区别——无论有没有 accept-charset="ISO-8859-1" 属性,sn-p 都显示相同的结果。例如。在这两种情况下,字符 %&amp;' 都会给出结果 fname=%25%26%27&amp;lname=
            【解决方案10】:

            我在 3 到 4 天前遇到了同样的问题。我正在使用 Angular 和 ASP。 就像上面的答案一样,我也不得不使用 URLDecode。

            回答您的问题:- 我为什么要对用户输入进行编码?


            避免意外行为

            假设您的应用程序可以处理 GET 请求中的两个参数。

            这只接受一个参数
            localhost:5000/stalls?searchbook=

            这需要两个参数
            localhost:5000/stalls?searchbook=&amp;includesecret=

            您还有一个可以搜索书籍的页面。
            用户在搜索栏中输入的任何内容都会产生 GET 请求。
            localhost:5000/stalls?searchbook=USERSTRINGGOESHERE

            如果用户要搜索 &amp;includesecret=true
            结果 GET 请求 localhost:5000/stalls?searchbook=&amp;includesecret=true 并可能意外导致私有数据在结果页面上泄露给用户。

            通常编码的符号(空格、&、% 等)在很多时候可能意味着不同的东西。 '&' 分隔 GET 请求中的键,也可以是字符串的一部分,因此在不编码的情况下使用它可能会导致预期的行为。

            P.S:- 不应通过 GET 请求查询私有数据。只是为了这个例子:)


            一致性

            在测试我的应用程序时,我注意到 PhantomJS 默认编码字符串。这样我在不同的客户中得到了不同的搜索结果。因此可以安全地假设即使您不这样做,某些客户端也可能对 URL 进行编码。


            另一个例子

            “#”键可以是 URL 的一部分。如果我访问localhost:5000/homepage.html#footer,带有 ID 页脚的元素就会显示出来。这也可能导致您不期望的行为。尝试在未编码或未清除非字母字符的 GET 请求参数中输入 #,您很可能会遇到与我类似的情况。如果我在其中输入 # (当它未编码时),我几天前写的搜索功能会中断。

            【讨论】:

              【解决方案11】:

              您可以将所有 %20 替换为空格。

              string values = "Key%20Date%20%26%20Times"; string decodeString = values.replace(/%20/g,' ');

              【讨论】:

                【解决方案12】:

                你说你的主要问题是:

                为什么我要担心编码隐藏输入框的值 以一种形式。我原以为这会为你处理好。

                嗯,答案是因为否则可能会导致注入问题。 (此外,隐藏字段不是存储敏感信息的地方,我想知道为什么隐藏该输入,而且隐藏不会改变它的行为方式......)

                为了解决您的问题,您可以混合使用 htmlEscape 和字符串替换功能,就像在回答这个问题 (Encode hidden form field value) 中一样

                function htmlEscape(str) {
                    return String(str)
                        .replace(/&/g, '%26')
                        .replace(/ /g, '%20');
                }
                

                希望对你有帮助。

                【讨论】:

                • 编写自己的逃生程序是个坏主意。请改用this 等内置方法。
                猜你喜欢
                • 2016-06-30
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2021-01-01
                相关资源
                最近更新 更多