在使用jQuery.serialize()进行序列化时,如何* HTML * - 编码表单内容?

时间:2015-04-16 08:25:32

标签: javascript jquery serialization url-encoding html-encode

jQuery表单.serialize()方法将表单内容序列化为字符串,并自动 URL - 对字符串进行编码。然后,我的服务器会反转此过程,并在反序列化时对字符串进行URL解码。

但我需要做的是 HTML - 在表单序列化之前对表单内容进行编码。换句话说,如果用户将HTML输入到我的表单中的文本输入中,我希望使用HTML编码使其安全,然后完全按照上述描述进行传输(使用URL编码正常)。

让我举一个例子说明:

使用.serialize()

的当前实现
  
      
  1. 用户将My name is <b>Fred</b>输入名称为Details的表单输入。
  2.   
  3. .serialize()将此序列化为Details=My+name+is+%3Cb%3EFred%3C%2Fb%3E (网址编码)
  4.   
  5. 服务器反序列化字符串并获取My name is <b>Fred</b> (URL解码)
  6.   

我想要发生什么

  
      
  1. 用户将My name is <b>Fred</b>输入名称为Details的表单输入。
  2.   
  3. 这会将HTML编码转换为My name is &lt;b&gt;Fred&lt;/b&gt; (HTML编码)
  4.   
  5. .serialize()将其序列化为Details=My+name+is+%26lt%3Bb%26gt%3BFred%26lt%3B%2Fb%26gt%3B(网址编码)
  6.   
  7. 服务器URL解码字符串并获取My name is &lt;b&gt;Fred&lt;/b&gt; (仅限URL解码)
  8.   

我希望.serialize()可以采用一个参数来指定表单内容应该是HTML编码的,但没有这样的运气。其他几种可能的解决方案是:

  1. 遍历表单输入并对其进行HTML编码&#34;手动&#34;在致电.serialize()之前:我宁愿不必这样做,因为它会使代码变得更加麻烦且不那么健壮。
  2. 修改我的服务器以接受非HTML编码的值:由于各种原因,我不会进入此问题,而不是一个实际的解决方案。
  3. 是否有更简单的解决方案?

5 个答案:

答案 0 :(得分:1)

当您使用MVC(请参阅注释)时,只需将[AllowHtml]属性应用于需要它的单个属性上方。

如果不存在,您将需要添加以下using语句:

using System.Web.Mvc;

注意:如果您还使用MetadataTypeAttribute,它可能无法开箱即用(但在这种情况下不太可能出现问题)

更新

从注释中,由于无法修改表单数据属性(动态表单),因此可以使用控制器操作上的以下内容在控制器中将其关闭

[ValidateInput(false)] 

您还可以更改整个服务器的设置(安全性较低)。请参阅此博客条目:

http://weblogs.asp.net/imranbaloch/handling-validateinputattribute-globally

答案 1 :(得分:0)

默认情况下,输入值始终会被编码。正如您所说,您必须遍历每个值才能先解码。您可以使用以下jQuery代码段来执行此操作:

$('<div/>').html(value).text();

答案 2 :(得分:0)

解决方案是使用jQuery的.serializeArray()并将HTML编码应用于循环中的每个元素。

换句话说,我不得不改变这个:

$.ajax({
    url: form.attr('action'),
    async: false,
    type: 'POST',
    data: form.serialize(),
    success: function (data) {
        //...
    }
});

到此:

// HTML-encode form values before submitting
var data = {};
$.each(form.serializeArray(), function() {
    data[this.name] = this.value
        .replace(/&/g, '&amp;')
        .replace(/"/g, '&quot;')
        .replace(/'/g, '&#39;')
        .replace(/</g, '&lt;')
        .replace(/>/g, '&gt;');
});

$.ajax({
    url: form.attr('action'),
    async: false,
    type: 'POST',
    data: data,
    success: function (data) {
        //...
    }
});

答案 3 :(得分:0)

一个选项可能是直接更新jquery库并在uriEncode发生之前调用dom值上的htmlEncode。

我在ASP.NET / MVC应用程序中对此进行了测试,并且我在jquery-1.8.2.js(第7222行,取决于版本)中更新的行是:

        s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );

        s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( htmlEncode(value) );

使用您认为合适的htmlEncode方法,但它似乎有效。

实际上可能更有意义扩展此方法并调用执行htmlEncode的customSerialize方法。

我相信这是最简单的方法,这意味着你不必在调用serialize之前迭代dom。

答案 4 :(得分:-1)

字符串必须在经过任何其他更改之后进行html编码,如url-encoding或sql string-escape。
因此,您首先序列化您的字符串,在链接中使用它, 反序列化后对其进行html编码。就像以前一样,但使用下面的功能。

为什么这很重要?

因为我可以自己输入一个非html转义的字符串,然后就可以给你了。你会认为它已经逃脱了,但事实并非如此。解决方案是在将其打印到页面上之前将其转义。

此问题描述了如何html-escape字符串:HtmlSpecialChars equivalent in Javascript?

function escapeHtml(text) {
  var map = {
    '&': '&amp;',
    '<': '&lt;',
    '>': '&gt;',
    '"': '&quot;',
    "'": '&#039;'
  };

  return text.replace(/[&<>"']/g, function(m) { return map[m]; });
}