ajax 05: ajax辨析

最近在多个知识点涉及到了ajax请求,各个知识有所交错,知识体系上学的有些混乱,这里梳理一下

单纯的发送ajax请求

方式1: ajax传统4步骤

  1. 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+"")
  1. 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请求

  1. 封装的代码
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()
  1. 前端调用的代码
<!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函数,接收第一层回调函数转手后的数据,然后完成自定义操作

posted @ 2022-08-05 09:05  nefu-xun  阅读(39)  评论(0编辑  收藏  举报