AJAX 学习

AJAX

一、基本理论

1、定义

AJAX 是一种从网页访问 Web 服务器异步无刷新技术。

  • 异步:同步是必须等待请求返回结果之后,才能继续其他操作。异步是可以在等待的时间里去继续其他操作,当响应就绪后对响应进行处理。
  • 无刷新:按需加载。(当点击查看更多的时候,就会结合DOM向服务器请求将数据追加进去,并没有刷新页面)
  • 无刷新场景:如果要让用户留在当前页面中,同时发出新的HTTP请求,就必须用JavaScript发送这个新请求,接收到数据后,再用JavaScript更新页面,这样一来,用户就感觉自己仍然停留在当前页面,但是数据却可以不断地更新。

AJAX (异步 JavaScript 和 XML)仅仅组合了:

  • 浏览器内建的 XMLHttpRequest 对象(从 web 服务器请求数据)
  • JavaScript 和 HTML DOM(显示或使用数据)

AJAX的缺点:

  • 没有浏览历史,不能回退
  • 存在跨域问题
  • SEO不友好,因为所有的信息不是全部加载的,所以爬虫爬不到。

2、工作原理

在这里插入图片描述

在这里插入图片描述

3、异步编程

(1)与同步编程的区别:

同步按你的代码顺序执行,异步不按照代码顺序执行,异步的执行效率更高。
在这里插入图片描述

(2)使用异步编程的场景:

我们利用主线程完成简短、快速的操作,利用子线程完成消耗时间长的事情。因为子线程独立于主线程,所以即便出现阻塞也不会影响主线程的运行。

**子线程的局限:**一旦发射了以后就会与主线程失去同步,我们无法确定它的结束,如果结束之后需要处理一些事情,比如处理来自服务器的信息,我们是无法将它合并到主线程中去的。

解决局限:JS中的异步操作函数通过回调函数来实现异步任务的结果处理

(3)回调函数

作用:它是在我们启动一个异步任务的时候告诉他:等他完成了这个任务之后要干什么。这样一来主线程几乎不用关心异步任务的状态了,他自己会善始善终。

function print() {
    document.getElementById("demo").innerHTML="RUNOOB!";
}
// 第一个参数是回调函数。这个函数执行之后会产生一个子线程,子线程等待3秒,然后调用回调函数print,在命令行输出 "RUNOOB!"。在 setTimeout 函数执行之后主线程并没有停止
setTimeout(print, 3000);

// 简洁写法
setTmeout(function(){
    document.getElementById("demo").innerHTML="RUNOOB!";
},3000);

二、XML和JSON

1、XML和HTML的区别

  • XML(可扩展标记语言)是用来传输和存储数据。服务器将响应的结果以XML的形式返回给客服端。XML的标签是自定义的,用来表示一些数据。
  • HTML是用来在网页中呈现数据的。HTML都是预定义标签。

2、JSON

之前进行数据交换时使用的格式是XML,服务器端给客服端返回结果的时候都是XML的形式。前端的JS接受到这个结果之后,就会对这个XML文件进行解析。

现在使用的是JSON。

// xml
<student>
    <name>小敏</name>
	<age>18</age>
</student>
   
// JSON  
{"name":"小明","age":18}

三、HTTP

超文本传输协议(HTTP)的设计目的是保证客户端与服务器之间的通信。客户端(浏览器)向服务器提交 HTTP 请求;服务器向客户端返回响应。响应包含关于请求的状态信息以及可能被请求的内容。

在这里插入图片描述

1、常用方法GET 和 POST

在客户机和服务器之间进行请求-响应时,两种最常被用到的方法是:GET 和 POST。

  • GET - 从指定的资源请求数据。查询字符串(名称/值对)是在 GET 请求的 URL 中发送的:/test/demo_form.php**?name1=value1&name2=value2**
  • POST - 向指定的资源提交要被处理的数据。查询字符串(名称/值对)是在 POST 请求的 HTTP 消息主体中发送的:

2、请求报文 – 浏览器向服务器请求

格式和参数:

  • 请求行 (请求类型-- POST GET) (url路径) (HTTP版本)

  • 请求头 HOST:

    ​ Cookie:

    ​ Content-type:

    ​ User-Agent:

  • 空行

  • 请求体 uesrname=admin&&password=admin

每次请求的时候,是将以上四个部分进行拼接发送给服务端。

在这里插入图片描述

3、响应报文 – 服务器响应

格式和参数:

  • 响应行 (HTTP版本) (响应状态码 – 200) (响应字符串 – ok)

  • 响应头 HOST:

    ​ Cookie:

  • 空行

  • 响应体 – 里面是HTML内容

在这里插入图片描述

四、AJAX原理与实现

1、XMLHttpRequest 对象 — 与服务器交换数据

这个对象用于和服务器交换数据。这意味着可以更新网页的部分,而不需要重新加载整个页面。如果要将请求发送给服务器,需要利用对象的open()和send()方法。

(1)创建XHR对象
// 现代的(IE7+、Firefox、Chrome、Safari 以及 Opera)浏览器 -- 新建XMLHttpRequest对象
var request = new XMLHttpRequest();
// 老版本的 Internet Explorer (IE5 和 IE6) -- 新建ActiveXObject对象
var request = new ActiveXObject('Microsoft.XMLHTTP');
// 新旧版本混写:通过检测window对象是否有XMLHttpRequest属性来确定浏览器是否支持标准的XMLHttpRequest
var request;
if(window.XMLHttpRequest){
    request = new XMLHttpRequest();
}else{
    request = new ActiveXObject('Microsoft.XMLHTTP');
}
(2)XHR对象将请求发送到服务器 – XHR方法
a. open(method,url,async) 规定请求的类型、URL 以及是否异步处理请求:
  • 第一个参数指定是GET还是POST,第二个参数是文件在服务器上的位置,第三个参数指定是否使用异步,默认是true异步,所以不用写。
  • url – 服务器上文件的地址,该文件可以是任何类型的文件,比如 .txt 和 .xml,或者服务器脚本文件,比如 .asp 和 .php (在传回响应之前,能够在服务器上执行任务)
  • XMLHttpRequest 对象如果要用于 AJAX 的话,其 open() 方法的 async 参数必须设置为 true
request.open('GET', '/api/categories');
b. send()将请求发送到服务器
// GET请求不需要参数,POST请求需要把body部分以字符串string或者FormData对象传进去。
request.send();
c. GET 和 POST请求

一般情况下使用GET请求,因为它简单并且快速。但是以下情况会使用POST请求:

1、不使用缓存文件,需要更新服务器上的文件或者数据库

2、由于POST没有数据量的限制,所以向服务器发送大量数据的时候使用

3、POST更加稳定,所以发送包含未知字符的用户输入时,POST 比 GET 更稳定也更可靠

// 使用GET请求的时候,由于得到的是缓存的数据,所以可以向URL添加一个唯一的ID
xmlhttp.open("GET","/try/ajax/demo_get.php?t=" + Math.random(),true);
xmlhttp.send();

// 通过 GET 方法发送信息,请向 URL 添加信息:
xmlhttp.open("GET","/try/ajax/demo_get2.php?fname=Henry&lname=Ford",true);
xmlhttp.send();

2、XHR响应 – XHR属性

如果要获得来自服务器的响应,那么就要使用XMLHttpRequest 对象的 responseText (获得字符串形式的响应数据)或 responseXML(获得 XML 形式的响应数据。)属性。

document.getElementById("myDiv").innerHTML=xmlhttp.responseText;

3、onreadystatechange 事件 – XHR属性

当请求被发送到服务器,会根据服务器的处理状态readyState触发一些 onreadystatechange事件,执行一些基于响应的任务。以下是XMLHttpRequest 对象的三个重要的属性:

在这里插入图片描述

注意: onreadystatechange 事件被触发 4 次(0 - 4), 分别是: 0-1、1-2、2-3、3-4,对应着 readyState 的每个变化。

4、服务器页面 – ASP, PHP文件

5、AJAX的实现

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script>
function loadXMLDoc(){
    // 1、创建对象
    var request;
    if(window.XMLHttpRequest){
        request = new XMLHttpRequest();
    }else{
        request = new ActiveXObject('Microsoft.XMLHTTP');
    }
	// 2、初始化 设置类型和url. (请求报文,url是服务器的地址,后面也可以设置url参数。、/server是路径)
    request.open('GET', 'http://127.0.0.1:8000/server?a=100&b=200');
    
    // 设置请求头.一般会将用户的身份信息放入,用来在服务器当中验证
    request.setRequestHeader('Content-Type','');
    
    // 3、发送
    // POST请求设置请求体在send里面设置
    request.send();
    
    // 4、事件绑定
    // 由于AJAX的请求是异步的,所以需要通过回调函数获得响应 回调函数onreadystatechange
    request.onreadystatechange = function () { 
        // 判断HTTP请求是否完成
        if (request.readyState === 4) {
            // 判断这个请求是否成功
            if (request.status === 200) {
                // 处理服务端返回的结果,这是response报文的信息
                document.getElementById("myDiv").innerHTML=xmlhttp.responseText;
            } 
        } else {
            // HTTP请求还在继续...
        }
    }
    alert('请求已发送,请等待响应...');    
}  

</script>
</head>

<body>
<div id="myDiv"><h2>使用 AJAX 修改该文本内容</h2></div>
// 通过点击事件触发AJAX
<button type="button" onclick="loadXMLDoc()">修改内容</button>
</body>

</html>

五、jQuery AJAX

jQuery的AJAX完全封装的是JavaScript的AJAX操作,从而简化相应的操作。使用的时候注意要引用jQuery库。

1、通用的发送AJAX的请求 – ajax(url, settings)

  • jQuery在全局对象jQuery(也就是$)绑定了ajax()函数,可以处理AJAX请求。函数接受一个服务器的地址,以及一个可选的settings对象。
  • settings对象的选项:

在这里插入图片描述

// 发送一个GET请求,并返回一个JSON格式的数据
var jqxhr = $.ajax('/api/categories',{dataType:'json'});
用回调函数处理返回的数据和出错时的响应 – 类似Promise的链式操作

2、get()、post()

  • 封装的是GET请求,当传入发送的数据data的时候,data将被转换成query附加到URL上。
  • 封装的是POST请求,当传入发送的数据data的时候,根据contentType把data序列化成合适的格式。
(1)$.get(URL,callback); – 从服务器中请求数据

第二个参数是回调函数。第一个回调参数存有被请求页面的内容,第二个回调参数存有请求的状态。

// 使用 $.get() 方法从服务器上的一个文件中取回数据
$('button').click(function(){[
    $.get('demo.php',function(data,status){
        alert('数据' + data + '\n状态' + status)})
]})
(2) $.post(URL,data,callback); – 向服务器提交数据。
$("button").click(function(){
    $.post("/try/ajax/demo_test_post.php",
    // c
    {
        name:"菜鸟教程",
        url:"http://www.runoob.com"
    },
    function(data,status){
        alert("数据: \n" + data + "\n状态: " + status);
    });
});

3、getJSON

通过GET获取一个JSON对象

// 使用类似Promise对象的方法去处理回调
var jqxhr = $.getJSON('/path/to/resource', {
    name: 'Bob Lee',
    check: 1
}).done(function (data) {
    // data已经被解析为JSON对象了
});

4、安全限制

  • 问题:安全限制同用JavaScript写AJAX,无法进行跨域请求。

  • 解决方案:如果需要使用JSONP,可以在ajax()中设置jsonp: 'callback',让jQuery实现JSONP跨域加载数据。

    ​ 也可以使用CORS进行处理。

六、Axios

前端最热门的AJAX库。

1、引入Axios库

这里可以换成国内开源的,在BootCDN里面去找。

<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>

2、发送AJAX请求

  • jQuery使用回调函数处理返回的数据。而axios是使用promise进行处理。

  • 即可以处理post请求,也可以处理get请求

// 绑定事件
btn.onclick = function(){
    // 通用方法
    axios({
        //请求方法
        method:'POST',

        //url
        url: '/axios-server',

        //url参数
        params:{
            vip:10,
            level:30
        },

        //头信息
        headers:{
            a:100,
            b=200
        },

        //请求体参数
        data:{
            username:'admin',
            password:'admin'
        }
    }).then(response=>{
        // 获取响应信息
        console.log(response);
        // 获取响应状态码
        console.log(response.status);
    })    
}
// 发送get请求
axios.get('/axios-server',{
    //url参数
    params:{
        id:100,
        vip:7
    },
    
    //请求头信息
    headers:{
        name:'yyx',
        age:20
    }
}).then(value =>{
    console.log(value);
});
// then方法处理结果

七、fetch函数

fetch函数也可以发送AJAX请求

btn.onclick = function(){
    fecth('http://127.0.0.1.8000/fetcg-server?vip=10',{
        //请求方法
        method:'POST',
        
        // 请求头
        header:{
            name:'yyx'
        },
        
        // 请求体
        body:'username=admin'
    }).then(response=>{
        return response.json();
    }).then(response=>{
        console.log(response);
    });
}

八、AJAX的问题

1、问题 – 无法访问跨域资源

上面代码的URL使用的是相对路径。这意味着尝试加载的网页和 XML 文件都必须位于相同服务器上。如果使用绝对路径,默认情况下,JavaScript在发送AJAX请求时,URL的域名必须和当前页面完全一致。(浏览器的同源策略)

2、设置代理服务器实现

在同源域名下设一个代理服务器来转发,JavaScript负责把请求发送到代理服务器。代理服务器再把结果返回,这样就遵守了浏览器的同源策略。这种方式麻烦之处在于需要服务器端额外做开发。

'/proxy?url=http://www.sina.com.cn'

3、解决方案JSONP – 跨域加载数据

由于浏览器同源策略的限制,网页中无法通过AJAX请求非同源的接口数据。但是script标签不受浏览器同源策略的影响,可以通过src属性,请求非同源的js脚本。

JSONP的实现原理是通过script标签的src属性,请求跨域的数据接口,通过函数调用的形式,接受跨域接口响应回来的数据。

// 服务器接口的函数调用  - 调用refreshPrice
refreshPrice({"0000001":{"code": "0000001", ... });
// 回调函数
function refreshPrice(data) {
    var p = document.getElementById('test-jsonp');
    p.innerHTML = '当前价格:' +
        data['0000001'].name +': ' + 
        data['0000001'].price + ';' +
        data['1399001'].name + ': ' +
        data['1399001'].price;
}
// src属性请求跨域的服务器接口,这个接口返回一个函数的调用。调用的函数通过查询字符串的形式告诉服务器要调用哪个文件(callback)
<script src='http://api.money.126.net/data/feed/0000001,1399001?callback=refreshPrice'></script>

4、新的跨域策略:CORS(Cross-Origin Resource Sharing)

跨域能否成功,取决于对方服务器是否愿意给你设置一个正确的Access-Control-Allow-Origin,决定权始终在对方手中.

在这里插入图片描述

假设本域Origin是my.com,外域是sina.com,只要响应头Access-Control-Allow-Originhttp://my.com,或者是*,本次请求就可以成功。

OPTIONS请求

对于PUT、DELETE以及其他类型如application/json的POST请求,在发送AJAX请求之前,浏览器会先发送一个OPTIONS请求(称为preflighted请求)到这个URL上,询问目标服务器是否接受:

// 发送**`OPTIONS`请求**,询问服务器是否接受
OPTIONS /path/to/resource HTTP/1.1
Host: bar.com
Origin: http://my.com
Access-Control-Request-Method: POST

// 服务器必须响应并明确指出允许的Method
HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://my.com
Access-Control-Allow-Methods: POST, GET, PUT, OPTIONS
Access-Control-Max-Age: 86400

// 浏览器确认服务器响应的Access-Control-Allow-Methods头确实包含将要发送的AJAX请求的Method,才会继续发送AJAX,否则,抛出一个错误。 

OPTIONS请求*

对于PUT、DELETE以及其他类型如application/json的POST请求,在发送AJAX请求之前,浏览器会先发送一个OPTIONS请求(称为preflighted请求)到这个URL上,询问目标服务器是否接受:

// 发送**`OPTIONS`请求**,询问服务器是否接受
OPTIONS /path/to/resource HTTP/1.1
Host: bar.com
Origin: http://my.com
Access-Control-Request-Method: POST

// 服务器必须响应并明确指出允许的Method
HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://my.com
Access-Control-Allow-Methods: POST, GET, PUT, OPTIONS
Access-Control-Max-Age: 86400

// 浏览器确认服务器响应的Access-Control-Allow-Methods头确实包含将要发送的AJAX请求的Method,才会继续发送AJAX,否则,抛出一个错误。 
  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值