Ajax与JQuery详解,跨域问题一文搞定(实例帮助理解)
Ajax
一、什么是Ajax
Ajax即Asynchronous Javascript And XML(异步JavaScript和XML)在 2005年被Jesse James Garrett提出的新术语,
用来描述一种使用现有技术集合的‘新’方法,包括: HTML 或 XHTML, CSS, JavaScript, DOM, XML, XSLT, 以及最重要的XMLHttpRequest。
[3] 使用Ajax技术网页应用能够快速地将增量更新呈现在用户界面上,而不需要重载(刷新)整个页面,这使得程序能够更快地回应用户的操作。 [3]
二、Ajax能做什么
Ajax能为我们做哪些东西
- 使用jQuery实现用户名的同步验证
- 使用jQuery实现注册邮箱的异步验证
- 使用JSON传递数据

Web 2.0的特点
- 用户贡献内容
- 内容聚合RSS
- 更丰富的“用户体验”

三、为什么使用Ajax
- 无刷新:不刷新整个页面,只刷新局部
- 无刷新的好处
- 只更新部分页面,有效利用带宽
- 提供连续的用户体验
- 提供类似于C/S的交互效果
例如:
谷歌地球,浏览器输入关键词,自动补齐

四、传统Web和Ajax的差异
差异对比图

Ajax:异步刷新技术

五、Ajax工作流程
流程图

注:
XML/JSON/HTML是用来封装请求或响应数据的众多数据格式中的一部分。还有如Script、JSONP、text等其他的数据格式。
后面在介绍jQuery提供的$.ajax()方法的dataType属性时会有说明。
六、XMLHTTPRequest
XMLHttpRequest对象介绍
- XMLHttpRequest是整个Ajax的核心
- 提供异步发送请求的能力
- 常用方法介绍
| 方法 | 说明 |
|---|---|
| open(String method,String url,boolean async,String user,String password) | 创建一个新的HTTP请求 |
| send(String data) | 发送请求到服务器端 |
| abort() | 取消当前请求 |
| setResponseHeader(String header,String value) | 设置请求的某个HTTP头信息 |
| getResponseHeader(String header) | 获取响应的某个HTTP头信息 |
| getAllResponseHeader() | 获取响应的所有HTTP头信息 |
1.open()方法
参数method:设置HTTP请求方法;参数url:请求的URL地址;…
其中:method参数值大小写不敏感,常用值有get、post等;
2. send()方法
data为发送此请求时携带的参数。data参数值取决于open方法中的method参数,如果method值为“POST”,需要指定该参数。如果method值为“GET”,该参数为null
3. setRequestHeader()方法
参数header:要指定的HTTP头名称;参数value:对应的值。
回调函数
- 事件
- onreadystatechange:指回调函数
- 常用属性
- ready State:XmlHttpRequest的状态信息
就绪状态码表格(重要!!!):
| 就绪状态码 | 说明 |
|---|---|
| 0 | XMLHttpRequest对象未完成初始化 |
| 1 | XMLHttpRequest对象开始发送请求 |
| 2 | XMLHttpRequest对象的请求发送成功 |
| 3 | XMLHttpRequest对象开始读取响应 |
| 4 | XMLHttpRequest对象读取响应结束 |
- 常用属性
- status:HTTP的状态码
| 状态码 | 说明 |
|---|---|
| 200 | 服务器正确返回响应 |
| 404 | 请求的资源不存在 |
| 500 | 服务器内部错误 |
| 403 | 没有访问权限 |
| … | … |
- status Text:返回当前请求的响应状态
- response Text:以文本格式获得响应的内容
- resposeXml:将XML格式的响应内容解析成DOM对象返回
使用Ajax验证用户名

实现效果图示例:



代码:
JSP:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>ajax1</title>
<script>
//创建XmlHttpRequest对象的方法
function createXmlHttpRequest(){
if (window.XMLHttpRequest){
//普通浏览器生成XmlHttpRequest对象的方法
return new XMLHttpRequest();
}else{
//IE浏览器生成XmlHttpRequest对象的方法
return new ActiveXObject("Microsoft.XMLHTTP");
}
}
//定义全局变量
var xmlHttpRequest;
function checkUserName(){
//当用户名输入框失去焦点时,进行验证
var userName=document.getElementById("userName").value;
//1.创建XmlHttpRequest(ajax引擎)
xmlHttpRequest=createXmlHttpRequest();
//2.定义URL
var url="ajaxServlet";
//3.设置回调函数
//提示 callBack不加括号
xmlHttpRequest.onreadystatechange=callBack;
//4.打开请求
/**
* 参数1 method 请求方式
* 参数2 url 请求地址
* 参数3 async 是否异步请求 true为是
*/
xmlHttpRequest.open("post",url,true);
//5.设置请求头
xmlHttpRequest.setRequestHeader("content-Type","application/x-www-form-urlencoded");
//6.发送请求
var data="userName="+userName;
xmlHttpRequest.send(data);
}
//回调函数
function callBack(){
//只有状态码是200才是正确的,为避免url填写错误,返回错误的值,做出不合适的响应
if (xmlHttpRequest.readyState == 4) {
//加载完成
//就绪状态码为4时,响应结束
document.getElementById("loading").style.display = 'none';
if(xmlHttpRequest.status==200) {
alert("200:"+xmlHttpRequest.responseText);
var result=xmlHttpRequest.responseText;
//将服务器返回的json字符串,转换为JSON对象
var jsonResult = eval('[' + result + ']');
alert(jsonResult);
alert(jsonResult[0].msg);
//显示提示语
document.getElementById("userNameTips").innerHTML=jsonResult[0].msg;
}else if (xmlHttpRequest.status==404){
alert("404:请求的资源不存在");
}else if (xmlHttpRequest.status==500){
alert("500:请求的服务器错误");
}else {
alert("未知错误");
}
} else {
//就绪状态为正确响应结束
document.getElementById("loading").style.display = 'block';
}
}
</script>
</head>
<body>
用户名:<input type="text" id="userName" onblur="checkUserName()"><span id="userNameTips"></span>
<img id="loading" src="images/loading.gif" width="15" height="15" style="display: none"/>
</body>
</html>
Servlet:
package cn.ebuy.servlet;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
@WebServlet(urlPatterns = "/ajaxServlet")
public class AjaxServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("application/json;charset=UTF-8");
PrintWriter out=resp.getWriter();
String userName=req.getParameter("userName");
//Json
Map map=new HashMap();
/*try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}*/
if ("admin".equals(userName)){
map.put("code","1001");
map.put("state",false);
map.put("msg","ajax-1用户名已占用");
out.println(JSON.toJSON(map));
}else {
map.put("code","1000");
map.put("state",true);
map.put("msg","ajax-1用户名可以使用");
out.println(JSON.toJSON(map));
}
}
}
jQuery实现Ajax
一、为什么要用jQuery实现Ajax
- 传统方式实现Ajax的不足
- 步骤繁琐
- 方法、属性、常用值较多不好记忆
- 处理复杂结构的响应数据(如XML格式)比较繁琐
- 浏览器兼容问题

二、$.ajax()简介
语法
-
$.ajax([settings]); -
常用属性参数
| 参数 | 类型 | 说明 |
|---|---|---|
| url | String | 发送请求的地址,默认为当前页地址 |
| type | String | 请求方式,默认为GET |
| data | PlainObject或String或Array | 发送到服务器的数据 |
| dataType | String | 预期服务器返回的数据类型,包括:XML、HTML、Script、JSON、JSONP、text |
| timeout | Number | 设置请求超时时间 |
| global | Boolean | 表示是否触发全局Ajax事件,默认为true |
| beforeSend | Function(jqXHR jqxhr,PlainObject settings) | 发送请求前调用的函数 |
| success | Function(任意类型 result,String textStatus,jqXHR jqxhr) | 请求成功后调用的函数参数result:可选,由服务器返回的数据 |
| error | Function(jqXHR jqxhr,String textStatus,String errorThrown) | 请求失败调用的函数 |
| complete | Function(jqXHR jqxhr,String textStatus) | 请求完成后(无论成功还是失败)调用的函数 |
注:
jqxhr中有status属性(200,500,404等状态码)
$.ajax()等价于jQuery.ajax(),该方法是jQuery提供的最底层的Ajax方法
三、实例
实现上述的用户名验证:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>ajax2</title>
<script src="js/jquery.js">
</script>
<script>
function checkUserName(){
var userName=$("#userName").val();
$.ajax({
url:'ajaxServlet',
type:'post',
async:false,
data:{
userName:userName
},
dataType:'json',
beforeSend:function (){
//alert("beforeSend");
$("#loading").show();
},
success:function (data){
//alert("success");
alert(data.code+"\t"+data.state+"\t"+data.msg);
//$("#userNameTips").html(data.msg);
},
error:function (){
alert("error");
},
//类似于java的finally
complete:function (){
alert("complete");
$("#loading").hide();
}
})
}
</script>
</head>
<body>
用户名:<input type="text" id="userName" onblur="checkUserName()"><span id="userNameTips"></span>
<img id="loading" src="images/loading.gif" width="15" height="15" style="display: none"/>
</body>
</html>
四、小拓展:
1.$.get()
function checkUserName(){
var userName=$("#userName").val();
$.get('ajaxServlet','userName='+userName,function (data){
alert(data.msg);
})
}
2.$("#").load()
function checkUserName(){
var userName=$("#userName").val();
$("#userNameTips").load('ajaxServlet',"userName="+userName);
3.$.getJson()
function checkUserName(){
var userName=$("#userName").val();
$.getJSON('ajaxServlet',"userName="+userName,function (data){
alert(data.msg);
})
}
}
五、解决跨域请求
准备工作
首先创建运行两个tomcat服务器,用来准备
引出问题


那么该如何解决呢
回答是:JSONP
JSONP(JSON with Padding)是JSON的一种“使用模式”,可用于解决主流浏览器的跨域数据访问的问题。
由于同源策略,一般来说位于 server1.example.com 的网页无法与不是 server1.example.com的服务器沟通,而 HTML 的< script> 元素是一个例外。
利用 < script> 元素的这个开放策略,网页可以得到从其他来源动态产生的 JSON 资料,而这种使用模式就是所谓的 JSONP。用 JSONP 抓到的资料并不是 JSON,而是任意的JavaScript,用 JavaScript 直译器执行而不是用 JSON 解析器解析。
代码演示:
还是刚才的例子
8090请求端的jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>ajax2</title>
<script src="../js/jquery.js">
</script>
<script>
function checkUserName(){
var userName=$("#userName").val();
$.ajax({
url:'http://localhost:8088/testJson/testJson.jsp',
type:'get',
async:true,
data:{
userName:userName
},
dataType:'jsonp',
jsonpCallback:'myjsonp',
jsonp:'theFunction',
beforeSend:function (){
//alert("beforeSend");
$("#loading").show();
},
success:function (data){
//alert("success");
alert(data.code+"\t"+data.state+"\t"+data.msg);
//$("#userNameTips").html(data.msg);
},
error:function (){
alert("error");
},
//类似于java的finally
complete:function (){
alert("complete");
$("#loading").hide();
}
})
}
</script>
</head>
<body>
用户名:<input type="text" id="userName" onblur="checkUserName()"><span id="userNameTips"></span>
<img id="loading" src="../images/loading.gif" width="15" height="15" style="display: none"/>
</body>
</html>
接受响应端:jsp(这里我用jsp充当servlet了(jsp就是特殊的servlet))
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
String callback=request.getParameter("theFunction");
response.setContentType("application/json;charset=UTF-8");
out.println(callback+"("+"{\"msg\":\"ajax-1用户名可以使用\",\"code\":\"1000\",\"state\":true}"+")");
%>
强调一下以下几个参数:
| 参数名 | 参数值 | 解释 |
|---|---|---|
| type | get | 跨域请求必须是get请求 |
| dataType | jsonp | 返回数据类型是jsonp |
| jsonCallback | myjsonp | 回调的函数名,参数值 |
| jsonp | theFunction | 请求端发送get请求的参数名 |
上图!!!


这样就解决问题了!!!
JSON
一、什么是JSON
JSON(JavaScript Object Notation)
JSON百度百科
- 一种轻量级的数据交互格式
- 采用独立于语言的文本格式
- 通常用于在客户端和服务器端之间传递数据
二、JSON的优点
- 轻量级交互语言
- 结构简单
- 易于解析
三、JSON语法
JSON语法
定义JSON对象
var JSON对象={"name":value,"name":value,...};
示例:
var person={"name":"张三","age":18,"flag":true};
定义JSON数组
语法
var JSON数组=[value,value,...];
示例:
var countryArray=["中国","美国","俄罗斯"];
var personArray=[{"name":"李四","age":18},{"name":"王五","age":19},{"name":"赵六","age":20}...]

浙公网安备 33010602011771号