07/7
2016
平时我们表单的提交多数是用action来指定提交到的文件,但这样会产生页面的刷新。用ajax提交可以避免刷新,但是需要我们自己组织要提交的数据。这就是表单序列化了。
jQuery有个serialize方法来做表单序列化,语法如下:
$(selector).serialize();
序列化之后,表单里需要提交的值会被组织成字符串,形如:
"name=124&company=baidu.com&fav=1,2,3"
如果里面有汉字之类,会自动进行url编码。表单序列化完全模拟了浏览器提交时的数据,这样我们就可以用ajax来提交表单了。
如一个id为“yy”的表单,它的提交的地址是"/plus/diy.php",提交按钮id是submit。那么表单序列化并提交的代码如下:
$("#submit").click(function(event) { event.preventDefault(); $.ajax({ type: "post", url: "/plus/diy.php", data: $("#yy").serialize(), success: function() { alert("信息提交成功。"); } }) })
注意用preventDefault()阻止浏览器默认事件(就是跳转到action页面,即使你没写action属性也会跳转的)。
后台对提交数据的处理和用action提交时的数据是一致的。
下面是用原生JavaScript代码定义的表单序列化函数serialize。
function serialize(form) { var parts = [], field = null, i, len, j, optLen, option, optValue; for (i = 0, len = form.elements.length; i < len; i++) { field = form.elements[i]; switch (field.type) { case "select-one": case "select-multiple": if (field.name.length) { for (j = 0, optLen = field.options.length; j < optLen; j++) { option = field.options[j]; if (option.selected) { optValue = ""; if (option.hasAttribute) { optValue = (option.hasAttribute("value") ? option.value : option.text); } else { optValue = (option.attributes["value"].specified ? option.value : option.text); } parts.push(encodeURIComponent(field.name) + "=" + encodeURIComponent(optValue)); } } } break; case undefined: //字段集 case "file": //文件输入 case "submit": //提交按钮 case "reset": //重置按钮 case "button": //自定义按钮 break; case "radio": //单选按钮 case "checkbox": //复选框 if (!field.checked) { break; } /* 执行默认操作 */ default: //不包含没有名字的表单字段 if (field.name.length) { parts.push(encodeURIComponent(field.name) + "=" + encodeURIComponent(field.value)); } } } return parts.join("&"); }
下面放个用原生XMLHttpRequest对象发送post异步请求的完整代码:
// function serialize(form)... 由于行数过长,此处省略具体代码,请自行引入serialize函数 var e = event || window.event; //firefox里的event是临时的,不是window下的全局变量 e.preventDefault ? e.preventDefault() : e.returnValue = false; //阻止浏览器默认事件(跳转) var postdata = serialize(document.querySelector("#form1")); //序列化表单 var xhr = new XMLHttpRequest(); //创建XMLHttpRequest对象 xhr.onreadystatechange = function() { //监听XMLHttpRequest请求状态 if (xhr.readyState === 4) { //XMLHttpRequest请求已完成 if (xhr.status === 200) { //如果返回的状态码为200 console.log(xhr.responseText); alert("数据提交成功"); } else { console.log("发生了异常,状态码为" + xhr.status + "," + xhr.statusText); } } } xhr.open("post", "/t/t.php", true); //打开XMLHttpRequest连接,url修改为自己用的 xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;"); //用post的时候一定要有这句,此句规定提交数据的格式。这个Content-Type适用不带附件的form表单;multipart/form-data适用于文件上传,text/plain则将数据以纯文本形式进行编码,其中不含任何控件或格式字符 xhr.send(postdata); //发送XMLHttpRequest请求
今天我实际使用这个方法的时候,一开始不知道要加Content-Type,搞得我花了半个多小时才找到问题。就是下面这句:
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;");