关于Ajax的那些事儿

Ajax作为WEB中一个重要的异步交互方式,其作用就不需要我在这里强调了,关于它的使用,我在项目中还是遇到了一些问题的,在这里我把它列出来,希望能够帮到大家。

出现的Bug:
1. Ajax无法解析从后台传过来的json数据
2. 后台报错了Ajax依然走了success方法
Bug复现:
Ajax无法解析从后台传过来的json数据
原始数据
解析json数据失败
源码:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%  String path = request.getContextPath();
	String basePath = request.getScheme() + "://" + request.getServerName() + ":" + 
		request.getServerPort() + path + "/";	
%>
<%@taglib uri="/struts-tags" prefix="s" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<base href="<%=basePath%>"/>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/javascript" src="js/jquery-1.11.3.js"></script>
<title>Insert title here</title>
</head>
<body>
	<form action="test/ajaxTest" method="post">
		姓名:<input type="text" id="account" name="account"/>
		密码:<input type="password" id="passcode" name="passcode"/>
		<input type="submit" value="提交"/>
	</form>
</body>
<script type="text/javascript">
	$(document).ready(function() {
		$("form").submit(function() {
			var form = $(this);
			$.ajax({
				type: form.attr('method'),
				url: form.attr('action'),
				data:{
					account: $("input[name=account]").val(),
					passcode: $("input[name=passcode]").val()
				},
				dataType: "json",
				success: function (data){
					alert("原始json数据:" + data);
					eachTest(data);
				},
				error: function(){
					alert("Network Error..." );
				}
			});
			return false;
		});
		function eachTest(data) {
			var json = data;
			//var json = eval("(" + data + ")");
			alert("获取json属性:json.account:" + json.account);
			$.each(json,function(key,value){
				alert(key + ": " + value);
			});
		}
	
	});
</script>
</html>  

关键在于最后的一个方法

	function eachTest(data) {
		var json = data;  
		//var json = eval("(" + data + ")");  
		alert("获取json属性:json.account:" + json.account);  
		$.each(json,function(key,value){  
		alert(key + ": " + value);  
		});  
	}

实际上从后台服务器获取的并不是json格式的数据,而是满足json格式的字符串,因此并不能直接当做
json来使用,直接对其进行解析的话就会解析不出来,需要对其转换

function eachTest(data) {
	//var json = data;  
	var json = eval("(" + data + ")");  
	alert("获取json属性:json.account:" + json.account);  
	$.each(json,function(key,value){  
	alert(key + ": " + value);  
	});  
}  

转换之后的效果:
解析json数据正常
这里简单说明一下Ajax关键方法的意思

$.ajax({
	type:   //这里填写的是ajax的提交方式,比如:"post","get"
	url:  //需要提交请求的地址,比如"https://www.google.com",  
			"user/userAction"
	data: //需要提交的数据,注意,是提交给服务器的数据
	dataType:  //服务器返回的的数据类型,比如"String","json"等
	contentType:  //ajax的上下文类型,如
					"application/x-www-form- urlencoded"(有时候解析不
					到json数据也可能是因为页面的cententType和表单/ajax的不
					一致导致的,具体可以打开调试 -- network -- 选择页面 --
					在Responce Headers这一栏(需要刷新一遍网页才会显示))
	success:  //表明ajax与后台连接成功后走的方法,可以有从后台返回的数据参数这
				里需要注意的是只要ajax与后台建立联系,就会走success方法,即使
				没有从后台获取到有用的数据,这里会有逻辑bug,下边有讲
	error:  //ajax与后台连接失败走的方法,一般会由于网络连接失败,但是也会有其他
				原因导致走error这个方法,比如你的url找不到,没有数据data等
});

查看contentType示例:
查看contentType示例
关于Ajax与后台建立完整连接以上的内容就可以满足

接下来我要讲讲关于使用Ajax编程的程序严谨性问题(在上边的程序片段注释中也提到过)

我们知道Ajax中的success方法是在ajax与后台服务器创建完整连接之后就会走的方法,并且可以返回从后台获取到的反馈数据,但是,这个反馈的数据是不是一定是我们需要的呢?能够获取到后台反馈数据,那是在后台程序执行正常的情况下才能成功,但是后台如果出现bug,那么你的ajax依旧执行了success方法,由于没有得到你需要的参数,所以你的页面是没有任何反馈(或者是动作)的

Bug复现:
后台报错了Ajax依然走了success方法

html>
<head>
    <title>Struts Problem Report</title>
    <style>
    	pre {
	    	margin: 0;
	        padding: 0;
	    }    
    </style>
</head>
<body>
    <h2>Struts Problem Report</h2>
    <p>
    Struts has detected an unhandled exception:
    </p>


<div id="exception-info">
<table>
    <tr>
        <td><strong>Messages</strong>:</td>
        <td>
            <ol>
                        <li>Connection refused: connect</li>
                        <li>Communications link failure

The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.</li>
                        <li>Could not open JDBC Connection for transaction; nested exception is com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.</li>
            </ol>
        </td>
    </tr>
    <tr>
        <td><strong>File</strong>:</td>
        <td>org/springframework/jdbc/datasource/DataSourceTransactionManager.java</td>
    </tr>
    <tr>
        <td><strong>Line number</strong>:</td>
        <td>245</td>
    </tr>
    
</table>
</div>


<div id="stacktraces">
<hr />
<h3>Stacktraces</h3>
<div class="stacktrace" style="padding-left: 0em">
    <strong>org.springframework.transaction.CannotCreateTransactionException: Could not open JDBC Connection for transaction; nested exception is com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.</strong>
    <div>
    <pre>
    org.springframework.jdbc.datasource.DataSourceTransactionManager.doBegin(DataSourceTransactionManager.java:245)
    org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:373)
    org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:439)
    org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:262)
    org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
    org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
    org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
    com.sun.proxy.$Proxy9.queryOneInfo(Unknown Source)
    com.cs.action.UserAction.signupCheckAccount(UserAction.java:53)
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    java.lang.reflect.Method.invoke(Unknown Source)
    ognl.OgnlRuntime.invokeMethod(OgnlRuntime.java:892)
    ognl.OgnlRuntime.callAppropriateMethod(OgnlRuntime.java:1537)
    ognl.ObjectMethodAccessor.callMethod(ObjectMethodAccessor.java:68)
    com.opensymphony.xwork2.ognl.accessor.XWorkMethodAccessor.callMethodWithDebugInfo(XWorkMethodAccessor.java:117)
    com.opensymphony.xwork2.ognl.accessor.XWorkMethodAccessor.callMethod(XWorkMethodAccessor.java:108)
    ognl.OgnlRuntime.callMethod(OgnlRuntime.java:1613)
    ognl.ASTMethod.getValueBody(ASTMethod.java:91)
    ognl.SimpleNode.evaluateGetValueBody(SimpleNode.java:212)
    ...... ......

这里是我从浏览器调试模块中截取的部分内容,大致意思是说数据库这一块出问题了,没有连接到数据库(因为我都没开数据库服务),这是我在做项目中偶然遇到的,一般我们的数据库服务器是一直开着的,但是我之前因为出门,就把电脑关了,数据库的服务顺带也关了,后来进行测试的时候,发现之前都没有动的程序怎么突然失灵了,然后在后台也没有看到bug,我以为是需要重启服务(应用程序服务,非数据库服务),但是重启之后还是没有用,程序检查了半天之后感觉没毛病,我就纳闷了,到底是哪里出了问题,我专门有对ajax的连接过程仔细检查了一遍,没毛病,我又专门写了个ajax的测试(没有使用到数据库),也没有毛病,这就尴尬了,这程序之前好好的,怎么现在就不听使唤了?然后我就抱着试试看的心态在浏览器调试中找找看,结果还真是找到了,原来是后台数据库方面除了bug,之前都没有往那边想,也没想去调试,毕竟后台都没有看到报错,其实这也奇怪,后台看不到报错,却能在浏览器中看到,有问题啊,不过总算找到问题来源了,这就好办了

关键来了,在这个过程中我们看到,即使你的ajax程序与后台创建了连接,也就是走了success方法,但是,这也并不能保证你能够从后台获取到你所需要的数据
可能很多人在使用ajax的时候根本就没有考虑到这个问题,以为走了success方法就算与后台创建连接了,也就自然而然的能够获取到自己所需要的信息(我之前也是这么认为的),那么今天看到这个例子,我想对大家编程的严谨性应该有一定的帮助

下边是我的对以上bug进行处理的代码(ajax部分):

$.ajax({
			type: "post",
			url: "user/signupCheckAccount",
			data:account.serialize(),
			dateType: "json",
			contentType: "application/x-www-form-urlencoded",
			cache: false,
			success: function(data){
				connectSuccess1(data)
			},
			error: function(){
				alert("Network error...");
			}
		});
function connectSuccess1(data){
		console.log(data);
		/*判断是否从后台获取到所需要的反馈数据,后台(主要是数据库)出故障仍然走succsee*/
			if(data.match("^\{(.+:.+,*){1,}\}$")){
				var flag = eval("(" + data + ")");
				$.each(flag,function(key,value){
					if(key == "SIGNUPCHECKACCOUNT_FLAG" && value == "success"){
						... ... 
					}else{
						$('#input-account-msg').html("*该账号已经被注册!请重新输入!");
						$('#input-account').focus().select();
					}
				});
		}else{
			alert("亲,出了点小问题,请稍后再注册!");
			var location = (window.location+'').split('/');
			var basePath = location[0]+'//'+location[2]+'/'+location[3];
			var url = basePath + '/homepage.jsp';
			window.location.href = url;
		}
	}

以上代码是我在写注册的时候用的,主要是用来从数据库检测用户输入的账号是否已经存在,对于以上出现的问题,我的处理办法(程序已经很明显了,我在啰嗦一遍)是先检查返回的数据是不是自己想要的,如果不是,说明后台肯定哪里是崩了,然后就不需要这么进行下去了,直接跳走,如果是,那就就请继续

以上就是我在ajax方面遇到的问题以及解决方案,希望对大家有帮助!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值