AJAX智能问题求解方法啊

(原创)mvc中ajax.beginform重复提交的问题解决 - 推酷
(原创)mvc中ajax.beginform重复提交的问题解决
最近处理mvc的一个小程序,废话不多说,程序很简单,如下图:
三块,采用load方式对数据进行操作,在处理提交的时候,出现了一个诡异的问题,我每一次提交的时候,都会将数据提交2次。
导致提交的数据被添加了2次,程序本身没有大的错误。
我们看一下三段的代码
leftindex(左边栏)
&!DOCTYPE html&
@Scripts.Render(&~/bundles/jquery&)
@Scripts.Render(&~/bundles/jqueryval&)
&meta name=&viewport& content=&width=device-width& /&
&script src=&~/Resouces/js/Commnon.js&&&/script&
$(document).ready(function () {
$(&#menu li a&).on(&click&, function () {
addwait();
$(&#main&).load($(this).attr(&ref&), function (response, status) {
if (status != &success&) {
alert(&加载失败 : & + status);
delwait();
&title&LeftIndex&/title&
&ul id=&menu&&
&li&&a href=&javascript:void(0)& title=&查看用户详情& ref=&/UserManager/UserList&&用户管理&/a&&/li&
&li&&a href=&javascript:void(0);& title=&查看用户详情& ref=&#&&查看设置用户组&/a&&/li&
&li&&a href=&javascript:void(0);& title=&查看用户详情& ref=&#&&查看设置权限组&/a&&/li&
&div id=&main&&
列表功能区域 userlist:
@model IEnumerable& SysDB.DB.TbUser&
&!DOCTYPE html&
@Scripts.Render(&~/bundles/jquery&)
@Scripts.Render(&~/bundles/jqueryval&)
&meta name=&viewport& content=&width=device-width& /&
&title&用户列表&/title&
&link href=&~/Resouces/Css/maincommon.css& rel=&stylesheet& /&
$(document).ready(function () {
$(&.btnadd&).on(&click&, function () {
$(&.dataarea&).hide(100);
$(&#setarea&).show(500);
function showarea() {
$(&.dataarea&).show(500);
$(&#setarea&).hide(100);
&div id=&main&&
&div id=&optarea&&
&div class=&btnadd fleft&&添加&/div&
&div class=&btndel fleft&&删除&/div&
&div class=&btnfind fleft&&查找&/div&
&div class=&dataarea&&
&table id=&uptb&&
&td width=&60px&&用户id&/td&
&td width=&160px&&用户姓名&/td&
&td width=&60px& &密码&/td&
@foreach (var item in Model)
&td&@item.id&/td&
&td&@item.username&/td&
&td&@item.password&/td&
&td&@Ajax.ActionLink(&添加&, &UserList&,new{strid=@item.id}, new AjaxOptions { HttpMethod=&post&, UpdateTargetId=&main&})&/td&
@Html.Partial(&addUserList&,Model);
添加部分:采用分布视图 adduserlist
&div id=&setarea& style=&display:&&
&div id=&setdata&&
@using (Ajax.BeginForm(&addUserList&, new AjaxOptions { HttpMethod = &POST&, UpdateTargetId = &setdata& }))
&p&用户id:&/p&
@Html.TextBox(&id&)
&p&用户帐号:&/p&
@Html.TextBox(&netname&)
&p&用户名:&/p&@Html.TextBox(&name&)
&input type=&submit& value=&提交2& id=&btnsub& /&
整体来看,看出什么地方有问题了么?对了,我的
@Scripts.Render(&~/bundles/jquery&)
@Scripts.Render(&~/bundles/jqueryval&) 语句被引用了两遍,一遍在left栏中,一遍在userlist中,他导致了jquery.unobtrusive-ajax.js文件被引用了2次,所以导致我在使用submit提交的时候生成了2个from,数据被重复提交2次。
所以各位在处理mvc的时候一定要注意js的引用,并且如果有能力自己写ajax的话还是自己写ajax比较方便。希望对新上手mvc的同学有帮助
已发表评论数()
请填写推刊名
描述不能大于100个字符!
权限设置: 公开
仅自己可见
正文不准确
标题不准确
排版有问题
主题不准确
没有分页内容
图片无法显示
视频无法显示
与原文不一致2222人阅读
AJAX(16)
&&& AJAX解决的问题就是“无刷新更新页面”,用传统的HTML表单方式进行页面的更新时,每次都要将请求提交到服务器,服务器返回后再重绘界面,这样界面就会经历:提交→变白→重新显示这样一个过程,用户体验非常差,使用AJAX则不会导致页面重新提交、刷新。
&&& AJAX最本质的实现是在Javascript中使用XMLHttpRequest进行Http的请求,开发中通常使用UpdatePanel、JQuery等方式简化AJAX的开发,UpdatePanel的方式实现AJAX最简单,但是数据通讯量比较大,因为要来回传整个ViewState,而且不灵活,对于复杂的需求则可以使用JQuery提供的ajax功能。
UpdatePanel的内部原理。
&&& AJAX最重要的问题是无法跨域请求(),也就是无法在页面中向和当前域名不同的页面发送请求,可以使用在当前页面所在的域的服务端做代理页面的方式解决。
&&& 在如鹏网项目中发帖的时候显示相关帖的功能、站内搜索项目中显示搜索Suggestion、数据采集项目中都用到了AJAX。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:281857次
积分:5234
积分:5234
排名:第3835名
原创:256篇
转载:43篇
评论:20条
(3)(20)(30)(30)(18)(30)(32)(31)(35)(19)(17)(4)(21)(9)随笔- 187&
&&&&&&&&&&&
本章解决在AJAX中常见的中文问题,分析中文乱码产生的原因,以及如何解决乱码问题
1. HTTP协议的编码规定
在HTTP协议中,浏览器不能向服务器直接传递某些特殊字符,必须是这些字符进行URL编码后再进行传送。url编码遵循的规则:
将空格转换为(+)
对0-9,a-z,A-Z之间的字符保持不变。
对于所有其他的字符,用这个字符的当前字符集编码在内存中的十六进制格式表示,并在每个十六进制字节前加上一个百分号%。例如,字符&+&用%2B表示,字符&=&用%3D表示,字符&&&用%26表示,字符&国&用%B9%FA表示注意,同一个中文字符在不同的字符集编码方式下,在内存中的编码值也是不同的,一个字符的URL编码是针对字符在内存中的码值而言的,采用不同编码的同一个字符的URL编码结果是不同的。
2. encodeURI()与encodeURIComponent()函数
javaScript中提供了两个函数来对字符进行URL编码:encodeURI()与encodeURIComponent(),两者的区别在于,encodeURI函数不会对以下的字符进行处理: &! @ # $ & * ( ) = : / ; ? + ' &,而encodeURIComponent函数会对更多的字符进行处理比如 URI的组成部分 &/& 就会被encodeURIComponent进行处理。这两个方法对传递的值进行URL编码,过程是先找到字符所对应的UTF-8编码,比如&张三&两个字的UTF-8编码是&0xE5BCA0E4B889&(前面的是零x,表示是16进制编码).&张&是&0xE5BCA0&,&三&是&0xE4B889&,那么被转换后的结果就
是&%E5%BC%A0%E4%B8%89&,注意这个转换结果与网页的编码没有任何关系,因为这两个函数总是拿到字符所对应的UTF-8码,然后再进行URL编码的。也就是说不管网页是GBK的编码还是UTF-8的编码,转换的结果都一样。
所以如果我们发送给服务器的请求包含有中文或者其它比较特殊的字符如空格&+&等符号的时候,就就需要使用者两个函数对字符进行URL编码。
3. 封装Ajax请求代码,供后面使用。
新建一个web项目,在web项目中添加一个ajax.js文件,内容包含两个函数如下:
createXmlHttp()
function createXmlHttp() {
if (window.XMLHttpRequest) {
//alert("非IE浏览器");
return new XMLHttpRequest();
} else if (window.ActiveXObject && !window.XMLHttpRequest){
var aVersion = ["MSXML2.XMLHttp.6.0",
"MSXML2.XMLHttp.5.0", "MSXML2.XMLHttp.4.0",
"MSXML2.XMLHttp.3.0", "MSXML2.XMLHttp",
"Microsoft.XMLHttp"];
for (var i = 0; i & aVersion. i++) {
var oXmlHttp = new ActiveXObject(aVersion[i]);
//alert("IE浏览器版本"+aVersion[i]);
return oXmlH
catch (ex) {}
throw new Error("创建XMLHttpRequest对象出错!");
doGet(url,callBack)函数,该函数有两个参数,将来要发送AjAX GET请求可以直接调用该方法。 第一个参数表示要发送的请求的URL地址,第二个是回调函数,回调函数需要处理从服务端返回的数据。
* @param url 请求的URL地址
* @param callBack 回调函数
function doGet(url,callBack){
var request=createXmlHttp();
request.onreadystatechange=function(){
if(request.readyState==4 && request.status==200){
//注意我们定义回调函数的时候要多加一个参数接收返回的数据
callBack(request.responseText);
request.open("GET",url);
request.send(null);
4. 编写页面,该页面使用的字符集是UTF-8编码:
&h3&验证用户名是否存在&/h3&
输入用户名:&input type="text" id="userName" /& &span id="warning"&&/span&&br /&
&input type="button" value="验证" onclick="checkUserName('userName')" /&
JavaScript部分:
首先引入ajax.js文件,然后编写当按钮点击的时候的要执行的代码:
&script type="text/javascript" src="ajax.js"&&/script&
&script type="text/javascript"&
function checkUserName(tagID){
//获取文本框中输入的值
var userName=document.getElementById(tagID).
//对中文进行URL编码
①var url="ajax.do?"+encodeURI("userName="+userName);
//data是从服务端返回来的数据
doGet(url,function(data){
document.getElementById("warning").innerHTML=
当在文本框中输入&张三&后,点击验证后,javaScript代码执行到 ① 之后,url的值就变成了 &ajax.do?userName=%E5%BC%A0%E4%B8%89&,可以通过firefox浏览器的firebug插件进行断点调试,得到发送的url的值。
这里为什么没有使用encodeURIComponent()函数呢?这是因为encodeURIComponent函数会将&=&变成&%3D&,&?&变成& %3F&, 如果有多个参数的话会用到&&&符号,同样也会被转换,而这些字符不用转换也可以提交,所以这里使用了encodeURI,这个函数不会对&?&,&=&,&&&进行转换。后面的&%E5%BC%A0%E4%B8%89&就是&张三&两个汉字按照UTF-8字符集进行URL编码之后的结果
5. 在服务端取得发送过来的数据
编写一个Servlet,这个Servlet的映射是 /ajax.do,其中的doGet方法如下:
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//告诉客户端响应的信息的编码格式是UTF-8
response.setContentType("text/charset=UTF-8");
②String userName=request.getParameter("userName");
PrintWriter out=response.getWriter();
out.print("您要验证的用户名是:"+userName+",该用户名可以使用");
我们在②处放置一个断点,然后以断点的方式启动Tomcat,提交后程序进入断点处我们发现取得的userName的值是: &??????&,为什么会是乱码?
我们分析一下,客户端Ajax想服务器发送的请求是
&ajax.do?userName=%E5%BC%A0%E4%B8%89&,那么服务器上的
request.getParameter()方法在取参数值的时候,首先要进行URL解码(其实就是去掉字符当中的&%&),解码之后将只剩下的字节部分按照Tomcat在内部默认的ISO-8859-1字符集的方式转换成字符串,于是乱码开始在这里出现 了。因为发送过来的字节在去掉%后剩下的字节应该按照UTF-8转换字符串才对,但是却采用了ISO-8859-1,于是乱码产生了。
那么知道原因之后,解决起来就很容易了。既然是按照ISO-8859-1转换得到的字符串,那我们就得到这个字符串还原为ISO-8859-1的字节,然后再将字节按照正确的UTF-8转换为字符串,这样就得到了正确的字符了,修改Servlet中的代码如下:
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//告诉客户端响应的信息的编码格式是UTF-8
response.setContentType("text/charset=UTF-8");
System.out.println("进入Servlet");
String userName=request.getParameter("userName");
userName=new String(userName.getBytes("iso-8859-1"),"UTF-8");
System.out.println(userName);
PrintWriter out=response.getWriter();
out.print("您要验证的用户名是:"+userName+",该用户名可以使用");
客户端响应为:
6. 试一试将提交方式改成POST方式
在ajax.js文件中添加一个函数,该函数专门用于提交POST请求
* @param url 要提交的URL
* @param submitData 要提交的数据
* @param callBack 回调函数
function doPost(url,submitData,callBack){
var request=createXmlHttp();
request.onreadystatechange=function(){
if(request.readyState==4 && request.status==200){
//注意我们定义回调函数的时候要多加一个参数接收返回的数据
callBack(request.responseText);
request.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
request.open("POST",url);
request.send(submitData);
修改页面上的javaScript代码:
&script type="text/javascript" src="ajax.js"&&/script&
&script type="text/javascript"&
function checkUserName(tagID){
//获取文本框中输入的值
var userName=document.getElementById(tagID).
//data是从服务端返回来的数据
doPost("ajax.do","userName="+userName,function(data){
document.getElementById("warning").innerHTML=
当我们发送post请求的时候,尽管我们为请求头设置了
application/x-www-form-urlencoded,但是发送的数据并没有进行URL编码,而传统的将form表单的提交方式设置成post,在提交的时候会自动进行URL编码。
所以Ajax中的post请求时将数据原封不动的传递到了服务器上,所以只需要调用reqeust.setCharacterEncoding() 设置正确的编码集后,就可以取出数据了。
7. 最佳解决方案
前面的方式我们虽然分别解决了GET方式和POST方式的中文问题,但是需要分开进行处理,并且对于不同的服务器,默认的编码集是不同的,这样对于GET方式我们进行的手工转码就不能通用了。
那么不管是Get请求还是POST,有没有可以统一的解决方案?我们可以做如下的处理:
将提交的数据使用javaScript的encodeURI()进行两次URL编码
服务端进行一次URL 解码即可
这种方式的优点是与客户端网页的编码集无关,与服务器的默认编码集无关,而且能够兼容几乎所有的浏览器。
下面以GET方式为例来理解分析全过程:
修改javaScript代码为:
&script type="text/javascript" src="ajax.js"&&/script&
&script type="text/javascript"&
function checkUserName(tagID){
//获取文本框中输入的值
var userName=document.getElementById(tagID).
//data是从服务端返回来的数据
var url="ajax.do? userName="+encodeURI(encodeURI(userName));
doGet(,function(data){
document.getElementById("warning").innerHTML=
Servlet代码修改为:
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//告诉客户端响应的信息的编码格式是UTF-8
response.setContentType("text/charset=UTF-8");
String userName=request.getParameter("userName");
userName=URLDecoder.decode(userName,"UTF-8");
System.out.println(userName);
PrintWriter out=response.getWriter();
out.print("您要验证的用户名是:"+userName+",该用户名可以使用");
运行后,在各种浏览器中都没有出现乱码问题。换成POST方式,也没有出现乱码问题。页面如果换成GBK编码,也没有出现乱码问题.
为什么这种方式没有出现问题,为什么要进行两次 encodeURI?我们只需要跟踪一下提交的数据即可:
假如我们提交的是 &张三&:
①我们第一次进行encodeURI之后的结果为:
%E6%9D%8E%E5%9B%9B
②第二次进行encodeURI之后的结果为:
%25E6%259D%258E%25E5%259B%259B
③我们对比一下两个值,发现第一次URL编码后中间有%,而第二次URL编码后将第一次编码结果中的%替换成了%25,所以最终发送的数据为:
ajax.do?userName=%25E6%259D%258E%25E5%259B%259B
④在服务端的Servlet中,我们通过调用request.getParameter(&userName&)取值的时候,getParameter方法会对%25E6%259D%258E%25E5%259B%259B进行URL解码,解码后的结果为%E6%9D%8E%E5%9B%9B,也就是将%25换成了%,那么此时Tomcat服务器按照默认的iso-8859-1转换的字符串的时候根本就没有做任何变换,还是%E6%9D%8E%E5%9B%9B
⑤当我们再次进行URL解码的时候即: URLDecoder.decode(userName,"UTF-8"),此时去掉其中的%后变成了E69D8EE59B9B,这正好是&张三&的UTF-8编码,所以使用UTF-8码转换成字符串&张三&.
从整个过程看来,这种方式的优势在于与页面的编码无关,也与服务器所使用的编码集无关。我们需要做的只需要将提交的数据(不管是POST的数据还是GET的数据),进行两次encodeURI即可。&
阅读(...) 评论()}

我要回帖

更多关于 问题求解 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信