ajax 05: ajax辨析
最近在多个知识点涉及到了ajax请求,各个知识有所交错,知识体系上学的有些混乱,这里梳理一下
单纯的发送ajax请求
方式1: ajax传统4步骤
- ajax的post请求
var xhr = new XMLHttpRequest()
xhr.onreadystatechange = function(){
if(this.readyState == 4){
if(this.status == 200){
//执行代码
}else{
//执行代码
}
}
}
xhr.open("POST", "/ajax/ajaxRequest4", true)
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded")
xhr.send("username="+username.value+"")
- ajax的get请求
var xhr = new XMLHttpRequest()
xhr.onreadystatechange = function(){
if(this.readyState == 4){
if(this.status == 200){
//执行代码
}else{
//执行代码
}
}
}
xhr.open("GET", "/ajax/ajaxRequest4?" + "username="+username+"", true)
xhr.send()
方式2:自己封装的ajax请求
- 封装的代码
function jQuery(selector){
if(typeof selector == "string"){
if(selector.charAt(0) == "#"){
//原先的dom对象还要留着,因为最终的实现还要用这些对象的方法去实现,我们无法完成
domObj = document.getElementById(selector.substring(1))
//但是由于封装了新方法,所以原先的dom对象就暂时不能用了(调用不了我们自定义的方法),要返回自定义的jQuery对象
return new jQuery()
}
}
if(typeof selector == "function"){
window.onload = selector
}
this.html = function(innerData){
domObj.innerHTML = innerData
}
this.click = function(fun){
domObj.onclick = fun
}
this.val = function(v){
if(v == undefined){
return domObj.value
}else{
domObj.value = v
}
}
this.change = function(fun){
domObj.onchange = fun
}
/**
* 有一些动态的数据不能写死
* 动态的信息有:
* 1. 请求的类型
* 2. 请求的地址
* 3. 是否异步
* 4. 提交的数据
*/
jQuery.ajax = function(jsonArgs) {
var method = jsonArgs.type.toUpperCase()
var xhr = new XMLHttpRequest()
//发送ajax请求,将文本框里的数据提交至后端
xhr.onreadystatechange = function () {
if (this.readyState == 4) {
if (this.status == 200) {
var jsonObj = JSON.parse(this.responseText)
jsonArgs.callBack(jsonObj)
} else {
alert("异常状态码: " + this.status)
}
}
}
if (method == "POST") {
xhr.open(method, jsonArgs.url, jsonArgs.async)
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded")
xhr.send(jsonArgs.data)
}
if (method == "GET") {
jsonArgs.data = "?" + jsonArgs.data
xhr.open(method, jsonArgs.url + jsonArgs.data, jsonArgs.async)
xhr.send()
}
}
}
$ = jQuery
new jQuery()
- 前端调用的代码
<!DOCTYPE html>
<html lang="en">
<head>
<title>全面测试自定义jQuery类库</title>
<meta charset="UTF-8">
</head>
<body>
<script src="/ajax/js/jQuery-1.0.0.js"></script>
<script>
$(function(){
$("#btn").click(function (){
$.ajax({
type : "POST",
data : "username=" + $("#username").val(),
async : true,
url : "/ajax/ajaxRequest10",
callBack : function(json){
$("#the-div").html(json.name)
//自定义回调函数,个性化的处理后端返回的数据
}
})
})
})
</script>
<input type="text" id="username">
<input type="button" id="btn" value="点击回显数据">
<div id="the-div"></div>
</body>
</html>
方式3:用官方jQuery封装的ajax请求
//$.ajax()的参数:一个json数据
$.ajax({
async : true, // 默认为true,可以不写
contentType : "application/json", // 一个字符串,表示从浏览器发送给服务器的参数的类型,可以不写
data : {"name" : "xun", "age" : 21, "address" : "芜湖"}, // 可以是字符串,数组,json,表示请求的参数和参数值,常用json格式
dataType : "json", // 表示期望从服务器端返回的数据格式,可选的有:xml,html,text,json
error : function(){ // 表示当请求发生错误时,执行的函数
//请求出错时,执行的代码
},
success : function(data){ // 请求成功,从服务器端返回了数据,执行success函数
//data,就是responseText,是jQuery处理之后的数据
},
url : 请求的地址,
type : "get" 或者 "post" // 请求的方式,默认为get方式,不区分大小写
})
//常用:url, data, dataType, success
ajax跨域请求问题
方式1:jsonp底层实现原理
//本质原理:通过自定义时机执行<script>标签,请求servlet
//创建script元素
var scriptElement = document.createElement("script")
//设置script元素属性
scriptElement.type = "text/javascript"
scriptElement.src = "http://localhost:8081/b/jsonp1?fun=sayHello"
//将script对象添加到body标签中(相当于完成了script标签的加载)
document.getElementsByTagName("body")[0].appendChild(scriptElement)
//后端返回数据时参照前端函数名返回,既完成了数据的返回,又可以在前端自定义的函数里对数据进行个性化操作
//这里还依赖一个原理:response.getWriter().writer("function" + (待返回数据填充进来))
//当把这个字符串返回给浏览器,浏览器得到:function(待返回数据),会执行该函数。这为后端返回数据给前端指定函数,提供了必要支撑
方式2:官方jQuery库提供的jonp方式
$.ajax({
type : "GET",
url : "http://localhost:8081/b/jsonp1",
dataType : "jsonp"
jsonp : "fun"
jsonCallback : "sayHello"
})
//dataType: "jsonp" 指定数据类型,从底层决定了,这次请求是一个类ajax请求,底层本质上不会使用XMLHttpRequest对象
//jsonp : "fun" 指定参数名,不设置的时候默认为"call back" ----> 指定第一层回调函数(主要用来作为入口,接受后端传来的json数据)
//jsonCallback : "sayHello" 指定回调函数的名字,不设置的时候,随即生成一个回调函数,且会调用success的回调函数----> 指定第二层回调函数(主要用于按照程序员需求处理后端传来的数据)
相比Ajax,为什么jsonp需要两层回调函数?
本质原因:jsonp不是ajax请求,没有用XMLHttpRequest,在真正的Ajax请求中,第一层回调函数被XMLHttpRequest.responseText替代,可以直接获取到后端传来的数据,只要显式的调用一次回调函数,将后端数据交给自定义的前端回调函数处理即可
但是在jsonp中享受不到XMLHttpRequest直接获取后端数据的便利,所以要在后端获取第一层回调函数,将后端数据传给前端,然后在该函数里,调用第二层回调函数,也就是我们自定义的函数或者是所谓的success函数,接收第一层回调函数转手后的数据,然后完成自定义操作