0
点赞
收藏
分享

微信扫一扫

AJAX基本原理和实现

Silence潇湘夜雨 2022-04-29 阅读 90

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超文本传输协议,协议规定了浏览器和万维网服务器之间互相通信的规则。

在这里插入图片描述

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

格式和参数:

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

  • 请求头 HOST:

    ​ Cookie:

    ​ Content-type:

    ​ User-Agent:

  • 空行

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

每次请求的时候,是将以上四个部分进行拼接发送给服务端。
在这里插入图片描述

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

格式和参数:

  • 响应行 (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>

五 、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,否则,抛出一个错误。 
举报

相关推荐

0 条评论