如何SerializeArray()还需要序列化Form中的HTML标记?

时间:2015-02-07 14:22:35

标签: jquery ajax serialization contenteditable inline-editing

我正在构建一个表单,允许用户向站点提交信息以供发布。我在可编辑的HTML标记上使用contenteditable=true进行内联编辑,我还使用标准表单输入,例如选择和文本字段。

当用户提交表单时,我希望它通过Ajax发生。我理解如何序列化表单本身但我不明白如何序列化同时设置contenteditable=true的HTML元素,以便它们在一个捆绑中运行到服务器。

以下是一些示例HTML代码:

<form action="/path/to/server/file" enctype="multipart/form-data">
<!--- Start WYSIWYG Inline Editing  --->
  <div id="ItemContainer">
    <h1 id="ItemTitle" contenteditable="true">A title would go here</h1>
    <h2 id="ItemSubtitle" contenteditable="true">A subtitle here</h2>
    <div id="ItemMainBody" contenteditable="true">
      <p>Integer condimentum sit amet, tempor elit odio, a dolor non ante at sapien. Sed ac lectus. Nulla ligula quis eleifend mi, id leo velit pede cursus arcu id nulla ac lectus. Phasellus vestibulum. Nunc viverra enim quis diam.</p>
      <p>Donec ullamcorper, risus tortor, pretium porttitor. Morbi quam quis lectus non leo.</p>
      <img src="/path/to/imagefile" /> 
    </div>
  </div>
<!--- End WYSIWYG Inline Editing. Standard Form elements follow... --->
  <select name="ItemCategory" id="ItemCategory">
    <option value="1">Planes</option>
    <option value="2">Trains</option>
    <option value="3">Automobiles</option>
  </select>
  <input type="text" name="ItemURL"  id="ItemURL">
<input type="submit" name="Submit" id="Submit" value="Submit"/>
</form>

要通过ajax提交,我现在会这样做:

('form').submit(function (e) {
        $.ajax({
            type: 'post',
            url: '/path/to/formprocessor',
            data: $('form').serializeArray(), // serializing the form
            dataType: "json",
            done: function (result) {
               // tell user its done!
            },
            error: function (result) {
                alert("An error has occured.");
            }
        });
        e.preventDefault();
    });

如何序列化HTML元素以便一起提交所有内容?我希望代表其名称的contenteditable元素的ID。所以在POST中我希望看到:

ItemCategory    1
ItemTitle   A title would go here
ItemSubtitle A subtitle here
ItemURL http://www.com
ItemMainBody <p>Integer condimentum sit amet, tempor elit odio, a dolor non ante at sapien. Sed ac lectus. Nulla ligula quis eleifend mi, id leo velit pede cursus arcu id nulla ac lectus. Phasellus vestibulum. Nunc viverra enim quis diam.</p>
      <p>Donec ullamcorper, risus tortor, pretium porttitor. Morbi quam quis lectus non leo.</p>
      <img src="/path/to/imagefile" /> 

2 个答案:

答案 0 :(得分:3)

在这种情况下,你必须在提交之前手动将参数添加到数组中,这里是JS代码:

('form').submit(function(e) {
  var formToSubmit = e.target;
  var serialisedFormArrayObject = $(formToSubmit).serializeArray();
  var $contentEditableItems = $("[contenteditable=true]");
  $contentEditableItems.each(function(index) {
    serialisedFormArrayObject.push({
      name: $contentEditableItems[index].id,
      value: $contentEditableItems[index].innerHTML
    });
  });
  $.ajax({
    type: 'post',
    url: '/path/to/formprocessor',
    data: serialisedFormArrayObject,
    dataType: "json",
    done: function(result) {
      // tell user its done!
    },
    error: function(result) {
      alert("An error has occured.");
    }
  });
  e.preventDefault();
});

  • 在澄清后编辑回答实际问题,但以下信息可能对其他人有用。

为了转义html字符串,您需要使用内置的Javascript方法encodeURIComponent。例如,如果你有:

console.log(encodeURIComponent("<div>potato</div>"));

您将获得:%3Cdiv%3Epotato%3C%2Fdiv%3E 根据您在服务器端使用的语言,您可以将其解码回来。

小心允许用户输入script标记,因为这可能导致Cross-site scripting (XSS) attacks

所以你需要更改一行

  

data:$(this).serializeArray(),//序列化表单

data: encodeURIComponent($(this).serializeArray()), // serializing the form

最后,如果您希望将表单作为查询字符串提交,而不是作为表单内容提交,则需要将动词设置为GET而不是POST

答案 1 :(得分:1)

尝试

$("form").click(function (e) {
    e.preventDefault();
    $("#ItemURL").val(location.href);
    var res = $(this).serializeArray(); // serializing the form
    // `serialize` `ItemContainer` elements to `{name:value}` pairs
    $("#ItemContainer *[id^=Item]")
    .each(function(i, el) {
        var j = {};
        j.name = el.id;
        j.value = $.trim(el.innerHTML);
        res.push(j)
    });
    $.ajax({
        type: "POST",
        url: "/echo/json/",
        data: {json:JSON.stringify(res)}, 
        dataType: "json",
        // substitute `success` for `done` _within_ `ajaxSettings` ,
        // utilize `.done` or `.then` _after_ , 
        // i.e.g., `$.ajax({}).done()` , `$.ajax({}).then()`
        success: function (result) {  
                // tell user its done!
                $("pre").text(JSON.stringify(result, null, 4))                   
            },
            error: function (result) {
                alert("An error has occured.");
            }
        });
    });

jsfiddle http://jsfiddle.net/guest271314/3zn4Lbab/