AJAX

定义:Ajax 在浏览器与 Web 服务器之间使用异步数据传输(HTTP 请求)。通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。

同步:必须等待前面的任务完成,才能继续后面的任务。

异步:不受当前任务的影响。

ajax请求的五个步骤java ajax请求步骤详细代码_客户端

(一)五大步骤

1、创建XMLHttpRequest对象,也就是创建一个异步调用对象.

var xmlhttp = new XMLHttpRequest();

2、创建一个新的HTTP请求,并指定该HTTP请求的方法、URL及验证信息.

/* * 规定请求的类型、URL 以及是否异步处理请求。 * open(method,url,async) * method:请求的类型;GET 或 POST * url:文件在服务器上的位置 * async:true(异步)或 false(同步) */ 例://get方式 xmlhttp.open("GET","ajax_info.txt",true); //post方式发送数据需要设置请求头 xmlhttp.open("post","test.php",true) xmlhttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded")

get和post(Http两种协议,基于TCP协议)
  • GET产生一个TCP数据包;POST产生两个TCP数据包。
  • 对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);
  • 而对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。通俗一点说:post请求的好比是看客户端发送请求前先告诉服务端即将发起请求,服务端告知客户端可以请求,客户端再将请求的信息带到服务端去
  • Post:post请求的参数会放到request body中,参数传递更加的安全,同时post支持多种编码方式
  • Get:请求的参数通过url传递,并且url的长度有限制,相对于Post而言更加不安全(参数直接暴露在url中), get请求的内容浏览器会自动的缓存

get的url:https://baijiahao.baidu.com/s? id=1626599028653203490&wfr=spider&for=pc

ajax请求的五个步骤java ajax请求步骤详细代码_服务器_02

3、发送HTTP请求

XMLHttpRequest.send(data); //data是个可选参数

4、设置响应HTTP请求状态变化的函数,并设置获取服务器返回数据的语句

XMLHttpRequest5种状态

发送HTTP请求的目的是为了接收从服务器中返回的数据。从创建XMLHttpRequest对象开始,到发送数据、接收数据、XMLHttpRequest对象一共会经历以下5种状态。

  • 0:未初始化状态。在创建完XMLHttpRequest对象时,该对象处于未初始化状态。
  • 1:初始化状态。在创建完XMLHttpRequest对象后使用open()方法创建了HTTP请求时,该对象处于初始化状态,还没有调用send()
  • 2:发送数据状态。在初始化XMLHttpRequest对象后,使用send()方法发送数据时,该对象处于发送数据状态。
  • 3:接收数据状态。Web服务器接收完数据并进行处理完毕之后,向客户端传送返回的结果。此时,XMLHttpRequest对象处于接收数据状态。
  • 4:完成状态。XMLHttpRequest对象接收数据完毕后,进入完成状态,此时XMLHttpRequest对象的readyState属性值为4。此时接收完毕后的数据存入在客户端计算机的内存中,可以使用responseText属性或responseXml属性来获取数据。

只有在XMLHttpRequest对象完成了以上5个步骤之后,才可以获取从服务器端返回的数据。因此,如果要获得从服务器端返回的数据,就必须要先判断XMLHttpRequest对象的状态。

Http状态码

1xx:信息响应类,表示接收到请求并且继续处理

2xx:处理成功响应类,表示动作被成功接收、理解和接受

3xx:重定向响应类,为了完成指定的动作,必须接受进一步处理

4xx:客户端错误,客户请求包含语法错误或者是不能正确执行

5xx:服务端错误,服务器不能正确执行一个正确的请求

200: 请求成功;

301: 当前请求的资源已被永久的移动到新的URI,返回的信息通常包含新的URI地址.

304: 所请求的资源未被修改,服务器返回状态码,不返回任何资源。客户端通常会缓存过访问的资源。

305: 当前请求的资源必须要通过代理进行访问

400: 客户端请求语法错误,服务端无法理解信息;

401: 请求要求用户完成认证,授权失败

403: 服务器拒绝执行当前请求;

404: 服务器无法根据用户请求找到相应的资源,没有发现文件、查询或URl

405: 客户端发起请求的方式被禁止;

410: 客户端请求的资源已经不存在;

415: 服务器无法处理请求附带的媒体格式;

500: 服务器内部错误;

501: 服务器不支持请求功能,无法完成请求;

503——服务器过载或暂停维修

505: 服务器不支持请求的Http协议的版本,无法完成请求;

当 readyState 等于 4 且状态为 200 时,表示响应已就绪

xmlHttpRequest.onreadystatechange = getData;

    //定义函数
    function getData() {
        //判断XMLHttpRequest对象的readyState属性值是否为4,如果为4表示异步调用完成
        if (xmlHttpRequest.readyState == 4) {
            //如果HTML文件不是在Web服务器上运行,而是在本地运行,则xmlHttpRequest.status的返回值为0。因此,如果该文件在本地运行,则应该加上xmlHttpRequest.status == 0的判断
            if (xmlHttpRequest.status == 200 || xmlHttpRequest.status == 0) { 
                document.write(xmlHttpRequest.responseText); //将返回结果以字符串形式输出
            }
        }
    }

5、获取返回的数据.

(二)代码:

1、get传递参数

var xhr = new XMLHttpRequest();
xhr.open("get", "http://localhost:3000/top/album?offset=0&limit=3",true);
xhr.send();
xhr.onreadystatechange = function () {
    if (xhr.status == 200 && xhr.readyState == 4) {
        console.log(xhr.responseText);
     }
}


//jquery
$.ajax({
   url:'http://localhost:3000/top/album?offset=0&limit=3',
   type:'GET',
   dataType: 'json',
   success:function(data) {
      console.log(data);
   }
})

2、post传递参数

var xhr = new XMLHttpRequest();
    xhr.open("post",
        "http://localhost:3000/top/album",
        true);
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xhr.send(`offset=0&limit=3`);
    xhr.onreadystatechange = function () {
        if (xhr.status == 200 && xhr.readyState == 4) {
            console.log(xhr.responseText);
        }
}

var xhr = new XMLHttpRequest();
    var data = {
        'offset': 0,
        'limit': 3
    }
    data = (function (obj) { // 转成post需要的字符串.
        var str = "";

        for (var prop in obj) {
            str += prop + "=" + obj[prop] + "&"
        }
        return str;
    })(data);
    xhr.open("post",
        "http://localhost:3000/top/album",
        true);
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    //data: offset=0&limit=3
    console.log(data)
    xhr.send(data);
    xhr.onreadystatechange = function () {
        if (xhr.status == 200 && xhr.readyState == 4) {
            console.log(xhr.responseText);
        }
    }

//jquery
$.ajax({
        url: 'http://localhost:3000/top/album',
        type: 'POST',
        dataType: 'json',
        data: {
            offset: 0,
            limit: 3
        },
        success: function (res) {
            console.log(res);
        },
        error: function (rej) {
            console.log(rej)
        }
    })

3、自己封装ajax方法

function ajax(options) {
        //存储默认值
        var defaults = {
            type: 'get',
            url: '',
            data: {},
            header: {
                'Content-Type': 'application/x-www-form-urlencoded'
            },
            success: function () {},
            error: function () {}
        }

        //使用options对象中的属性覆盖defaults对象中的属性
        Object.assign(defaults, options);

        var xhr = new XMLHttpRequest();

        var params = '';
        //循环用户传递进来的对象格式参数
        for (var attr in defaults.data) {
            //将参数转化为字符串格式
            params += attr + '=' + defaults.data[attr] + '&'
        }
        //将参数最后的&截取掉
        params = params.substr(0, params.length - 1)

        //判断请求方式
        if (defaults.type == 'get') {
            defaults.url = defaults.url + '?' + params
        }

        xhr.open(defaults.type, defaults.url);

        //如果请求方式为post
        if (defaults.type == 'post') {
            //请求参数类型
            var ContentType = defaults.header['Content-Type']
            xhr.setRequestHeader('Content-Type', ContentType);
            if (ContentType == 'application/json') {
                //传递json数据格式
                xhr.send(JSON.stringify(defaults.data))
            } else {
                //传递字符串拼接格式
                xhr.send(params)
            }
        } else {
            xhr.send();
        }

        xhr.onload = function () {
            //获取响应头数据
            var contenTtype = xhr.getResponseHeader('Content-Type')

            //服务器端返回的数据
            var responseText = xhr.responseText

            //判断是否包含application/json
            if (contenTtype.includes('application/json')) {
                //将json字符串转化为json对象
                responseText = JSON.parse(responseText)
            }

            //判断是否成功
            if (xhr.status == 200) {
                defaults.success(responseText, xhr);
            } else {
                defaults.error(responseText, xhr)
            }
        }
}

//get方式
    ajax({
        url: 'http://localhost:3000/top/album?offset=0&limit=3',
        type: 'GET',
        dataType: 'json',
        success: function (data, xhr) {
            console.log(data, xhr)
        },
})

//post方式
ajax({
        url: 'http://localhost:3000/top/album',
        type: 'POST',
        data: {
            offset: 0,
            limit: 3
        },
        dataType: 'json',
        success: function (data, xhr) {
            console.log(data, xhr)
        },
    })

4、对数据的操作

<div class="container">
        <p id="list"></p>
 </div>

var xhr = new XMLHttpRequest();
    xhr.open("get",
        "http://localhost:3000/search/hot",
        true);
    xhr.send();
    xhr.onreadystatechange = function () {
        if (xhr.status == 200 && xhr.readyState == 4) {
            var res = xhr.responseText;
            // 将res转换为json对象
            var lists = eval("(" + res + ")").result.hots;
            var data =(new Function("","return "+res))();
            
            console.log(lists)
            for (i = 0; i < 10; i++) {
                var dom = `<div class="songname">${lists[i].first}</div>`
                $("#list").append(dom)
            }
        }
}

//jquery
$.ajax({
        url: 'http://localhost:3000/top/album?offset=0&limit=3',
        type: 'GET',
        dataType: 'json',
        success: function (result) {
            var lists = result.monthData;
            for (i = 0; i < 10; i++) {
                console.log(lists[i].name);
                dom = `<div class = "songname">${lists[i].name}</div>`
                $("#list").append(dom)
            }
        }
})