Ajax入门到精通

一 Ajax概述

1.1 Ajax简介

AJAX 全称为 Asynchronous JavaScript And XML,就是异步的 JS 和 XML。 通过 AJAX 可以在浏览器中向服务器发送异步请求,最大的优势:无刷新获取数据。 AJAX 不是新的编程语言,而是一种将现有的标准组合在一起使用的新方式。

1.2 Ajax的特点

① AJAX 的优点

  • 可以无需刷新页面而与服务器端进行通信。
  • 允许你根据用户事件来更新部分页面内容。

② AJAX 的缺点

  • 没有浏览历史,不能回退
  • 存在跨域问题(向非同源URL发送请求)
  • SEO 不友好

1.3 Ajax前置知识

  • 学习发送Ajax请求之前,需要了解一些前置知识,比如两种数据交换的格式、HTTP相关知识点(少部分)。
  • 由于发送Ajax请求需要用到服务器,所以还需要简单了解下如何利用服务端框架Express搭建服务器。
  • 接下来会对这些知识做个简要的介绍。

二 两种数据交换格式

2.1 XML

  • XML 可扩展标记语言。
  • XML 被设计用来传输和存储数据。
  • XML 和 HTML 类似,不同的是 HTML 中都是预定义标签,而 XML 中没有预定义标签, 全都是自定义标签,用来表示一些数据。
比如说我有一个学生数据:
name = "孙悟空" ; age = 18 ; gender = "男" ;
用 XML 表示:
<student>
    <name>孙悟空</name>
    <age>18</age>
    <gender></gender>
</student>

2.2 JSON

  • JSON 是一种轻量级的数据交换格式。
  • 采用完全独立于编程语言的文本格式来存储和表示数据。
  • JSON 目前已经取代了XML。
JSON 表示:
{"name":"孙悟空","age":18,"gender":"男"}

JSON 对象主要有以下两个方法需要了解一下:

① 用于解析 JavaScript Object Notation (JSON) 的 parse() 方法。

const json = '{"result":true, "count":42}';
const obj = JSON.parse(json);

console.log(obj.count);
// expected output: 42
console.log(obj.result);
// expected output: true

② 用于将对象/值转换为 JSON字符串的 stringify() 方法。

console.log(JSON.stringify({ x: 5, y: 6 }));
// expected output: "{"x":5,"y":6}"

三 HTTP相关

3.1 HTTP简介

HTTP(hypertext transport protocol)协议『超文本传输协议』,协议详细规定了浏览器和万维网服务器之间互相通信的规则

这里我们只需要先了解下请求报文和响应报文的格式与参数,HTTP有很多其他知识点,需要学习的可以参考以下网站:

MDN学习文档:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Overview

3.2 请求报文和响应报文

① 请求报文

POST(请求方式) /s?ie=utf-8(URL) HTTP/1.1(协议版本)
Host: atguigu.com
Cookie: name=guigu
Content-type: application/x-www-form-urlencoded
User-Agent: chrome 83
空行
username=admin&password=admin

② 响应报文

HTTP/1.1(协议版本) 200 (响应状态码) OK(响应状态描述)
Content-Type: text/html;charset=utf-8
Content-length: 2048
Content-encoding: gzip
空行
<html><body>.....</body></html>

3.3 常见响应状态码

200 OK 请求成功。一般用于GET 与POST 请求
201 Created 已创建。成功请求并创建了新的资源
401 Unauthorized 未授权/请求要求用户的身份认证
404 Not Found 服务器无法根据客户端的请求找到资源
500 Internal Server Error 服务器内部错误,无法完成请求

四 Express搭建服务器

4.1 安装node.js

express要使用npm安装,而npm基于node.js,所以先安装node.js,node.js的安装比较简单,这里就不展开描述了。

http://nodejs.cn/

4.2 安装express(服务端框架)

安装完node.js,就要使用npm安装express框架。

① 首先给出我的目录结构

AJAX目录结构

② 初始化环境

E:\complete\AJAX>  npm init --yes

③ 下载express包

E:\complete\AJAX> npm install express --save

④ 编写js代码

//1. 引入express
const express = require('express');

//2. 创建应用对象
const app = express();

//3. 创建路由规则
// request 是对请求报文的封装
// response 是对响应报文的封装
app.get('/', (request, response)=>{
    //设置响应
    response.send('HELLO EXPRESS');
});

//4. 监听端口启动服务
app.listen(8000, ()=>{
    console.log("服务已经启动, 8000 端口监听中....");
});

⑤ 启动服务器

E:\complete\AJAX\代码\2-express框架> node express基本使用.js

启动服务器

⑥ 打开页面

服务器启动后的页面

4.3 安装nodemon自动重启工具

由于接下来会写一些例子,服务器相关代码都会存储在server.js中,每次重启服务器都输入指令很麻烦,所以这里安装一个自动重启的工具,只要修改完server.js后保存代码会自动重启服务器。

① 安装

npm install -g nodemon

② 启动服务

ndoemon server.js

五 发送AJAX请求的4种方式

5.1 原生AJAX

5.1.1 XHR

① XHR简介

  • XHR,是早期用于发送AJAX请求的方式。
  • XHR为发送服务器请求和获取响应提供了合理的接口。
  • XMLHttpRequest,AJAX 的所有操作都是通过该对象进行的。

学习网站:https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest

② XHR使用步骤

  1. 创建 XMLHttpRequest 对象
var xhr = new XMLHttpRequest(); 
  1. 设置请求信息
//请求准备
xhr.open(method, url); 
//可以设置请求头,一般不设置
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
  1. 发送请求
xhr.send(body) //get 请求不传 body 参数,只有 post 请求使用
  1. 接收响应
//xhr.responseXML 接收 xml 格式的响应数据
//xhr.responseText 接收文本格式的响应数据
xhr.onreadystatechange = function (){
if(xhr.readyState == 4 && xhr.status == 200){
	var text = xhr.responseText;
	console.log(text);
	}
}

备注:关于onreadystatechange,它是一个事件处理函数,在XMR对象上面有一个属性:readyState,该属性有多个值,表示当前处在请求/响应过程的哪个阶段,当该属性的值发送变化时,就会触发onreadystatechange事件。

readyState的值

5.1.2 GET和POST

接下来通过两个简单的例子,说明一下GET请求和POST请求。

① GET请求

案例效果

点击按钮返回响应信息

GET请求效果

服务器端 server.js

// 1. 引入express
const express = require('express');

// 2. 创建应用对象
const app = express();

// 3. 创建路由规则
app.get('/server', (request, response) => {
  // 设置响应头 设置允许跨域
  response.setHeader('Access-Control-Allow-Origin', '*');
  // 设置响应体
  response.send("Hello Ajax - 2");
});

// 4. 监听服务
app.listen(8000, () => {
  console.log("服务已经启动, 8000 端口监听中...");
 })

GET.html

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>AJAX GET 请求</title>
    <style>
        #result{
            width:200px;
            height:100px;
            border:solid 1px #90b;
        }
    </style>
</head>
<body>
    <button>点击发送请求</button>
    <div id="result"></div>
    <script>
        //获取button元素
        const btn = document.getElementsByTagName('button')[0];
        const result = document.getElementById("result");
        //绑定事件
        btn.onclick = function(){
            //1. 创建对象
            const xhr = new XMLHttpRequest();
            //2. 初始化 设置请求方法和 url
            xhr.open('GET', 'http://127.0.0.1:8000/server?a=100&b=200&c=300');
            //3. 发送
            xhr.send();
            //4. 事件绑定 处理服务端返回的结果
            xhr.onreadystatechange = function(){
                //判断 (服务端返回了所有的结果)
                if(xhr.readyState === 4){
                    //判断响应状态码 200-300 一般为成功
                    if(xhr.status >= 200 && xhr.status < 300){
                        //处理结果  行 头 空行 体
                        //响应 
                        console.log(xhr.status);//状态码
                        console.log(xhr.statusText);//状态字符串
                        console.log(xhr.getAllResponseHeaders());//所有响应头
                        console.log(xhr.response);//响应体
                        //设置 result 的文本
                        result.innerHTML = xhr.response;
                    }else{

                    }
                }
            }


        }
    </script>
</body>

控制台输出

GET请求控制台输出

GET请求参数

GET请求参数

② POST请求

鼠标放到div中,发post请求,将响应体放在div中呈现

案例效果

POST请求效果

server.js添加post

app.post('/server', (request, response) => {
  // 设置响应头, 设置允许跨域
  response.setHeader('Access-Control-Allow-Origin', '*');
  // 设置响应体
  response.send("Hello Ajax POST");
});

POST.html

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Ajax POST 请求</title>
  <style>
    #result {
      width: 200px;
      height: 100px;
      border: solid 1px #903;
    }
  </style>
</head>
<body>
  <div id="result"></div>
  <script>
    // 获取元素对象
    const result = document.getElementById('result');
    // 绑定事件
    result.addEventListener("mouseover", function(){
      // 1. 创建对象
      const xhr = new XMLHttpRequest();
      // 2. 初始化 设置类型(请求方式)与url
      xhr.open('POST', 'http://127.0.0.1:8000/server');
      // 3. 发送   设置请求参数(请求体)
      xhr.send('a=100&b=200&c=300');
      // 4. 事件绑定
      xhr.onreadystatechange = function(){
        // 判断
        if(xhr.readyState === 4){
          if(xhr.status >=200 && xhr.status < 300){
            // 处理服务端返回的结果
            result.innerHTML = xhr.response;
          }
        }
      }
    });
  </script>
</body>

open后,send前,xhr可以设置请求头信息,分为预定义请求头和自定义请求头

// 设置请求体内容的类型,预定义头信息
xhr.setRequesHeader('Content-Type','application/x-www-from-urlencoded');
// 自定义头信息
xhr.setRequesHeader('name', 'ykyk');

server.js中设置响应头允许自定义请求头 post要改成all,还要加上下面这行代码

response.setHeader('Access-Control-Allow-Header','*');

查看请求体

POST请求体

5.1.3 JSON数据请求

按下任意按键,返回JSON数据,显示到页面上

案例效果

JSON请求效果

server.js添加路由规则

app.all('/json-server', (request, response) => {
  // 设置响应头, 设置允许跨域
  response.setHeader('Access-Control-Allow-Origin', '*');
  // 设置响应头, 设置允许自定义头信息
  response.setHeader('Access-Control-Allow-Headers', '*');
  // 响应一个数据
  const data = {
    name: 'atguigu'
  };
  // 对 对象 进行 字符串 转换
  let str = JSON.stringify(data)
  // 设置响应体 
  response.send(str);
});

JSON.html

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>JSON</title>
  <style>
    #result {
      width: 200px;
      height: 100px;
      border: solid 1px #89b;
    }
  </style>
</head>
<body>
  <div id="result"></div>
  <script>
    const result = document.getElementById('result');
    // 绑定键盘按下事件
    window.onkeydown = function(){
      // 发送请求
      const xhr = new XMLHttpRequest();
      //设置响应体数据的类型(自动转换)
      xhr.responseType = 'json';
      // 初始化
      xhr.open('GET', 'http://127.0.0.1:8000/json-server');
      // 发送
      xhr.send();
      // 事件绑定
      xhr.onreadystatechange = function(){
        if(xhr.readyState === 4){
          if(xhr.status >= 200 && xhr.status < 300){
            console.log(xhr.response);
            // 1. 手动对数据转化 (字符串再转换成json)
            // let data = JSON.parse(xhr.response); //转换成json
            // result.innerHTML = data.name;
            // 2. (自动转换)自动转换(自动转换)
            result.innerHTML = xhr.response.name; //已经自动变成json
          }
        }
      }
    }
  </script>
</body>
5.1.4 IE缓存问题

问题:在一些浏览器中(IE),由于缓存机制的存在,ajax 只会发送的第一次请求,剩余多次请求不会在发送给浏览器而是直接加载缓存中的数据。

解决方式:浏览器的缓存是根据url 地址来记录的,所以我们只需要修改url 地址即可避免缓存问题

xhr.open("get","/testAJAX?t="+Date.now());
5.1.5 超时与网络异常

问题:有时由于网速的问题,导致发送的AJAX请求不能及时得到反馈,这时需要进行一些超时的处理。

解决方式:通过timeout属性设置超时时间,通过ontimeout设置超时回调函数,onerror设置异常回调函数

// 超时设置 (2秒)
xhr.timeout = 2000;
// 超时回调
xhr.ontimeout = function(){
	alert('网络超时,请稍后重试')
}
// 网络异常回调
xhr.onerror = function(){
	alert('网络异常,请稍后重试')
}
5.1.6 重复请求问题

问题:有时某些AJAX请求会被用户重复点击发送,导致服务器会接收到多个请求,造成不必要的压力。

解决方式:这时需要通过设置标识,通过判断标识,xhr对象调用abort(),将重复发送的请求及时取消。

<body>
    <button>点击发送</button>
    <script>
        //获取元素对象
        const btns = document.querySelectorAll('button');
        let x = null;
        //标识变量
        let isSending = false; // 是否正在发送AJAX请求

        btns[0].onclick = function(){
            //判断标识变量
            if(isSending) x.abort();// 如果正在发送, 则取消该请求, 创建一个新的请求
            x = new XMLHttpRequest();
            //修改 标识变量的值
            isSending = true;
            x.open("GET",'http://127.0.0.1:8000/delay');
            x.send();
            x.onreadystatechange = function(){
                if(x.readyState === 4){
                    //修改标识变量
                    isSending = false;
                }
            }
        }
    </script>
</body>

5.2 JQuery发送AJAX

  • JQuery中封装了对于AJAX请求的操作。
  • 但是通常不会为了发送AJAX请求,而特意引入JQuery,因为发送AJAX请求的部分只占JQuery的一部分而已,JQuery主要部分在于简化对于DOM的操作。
  • 除非本身就是依赖JQuery实现的项目,可以使用其提供的对于AJAX的操作。

学习网站:https://www.w3school.com.cn/jquery/jquery_ajax_intro.asp

5.2.1 GET请求
$.get(url, [data], [callback], [type])
  • url:请求的URL 地址
  • data:请求携带的参数
  • callback:载入成功时回调函数
  • type:设置返回内容格式,xml, html, script, json, text, _default
5.2.2 POST请求
$.post(url, [data], [callback], [type])
  • url:请求的URL 地址
  • data:请求携带的参数
  • callback:载入成功时回调函数
  • type:设置返回内容格式,xml, html, script, json, text, _default
5.2.3 通用方法
$.ajax({
	// url
	url: 'http://127.0.0.1:8000/jquery-server',
	// 参数
	data: {a:100, b:200},
	// 请求类型
	type: 'GET',
	// 响应体结果
	dataType: 'json',
	// 成功的回调
	success: function(data){console.log(data);},
	// 超时时间
	timeout: 2000,
	// 失败的回调
	error: function(){console.log('出错拉~');},
	// 头信息
	headers: {
		c: 300,
		d: 400
	}	
})

5.3 axios

  • Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。
  • 是目前主流前端框架,比如react和vue,推荐的发送AJAX请求的方式。
  • 使用时可以CDN引入或者npm安装。

学习网站:https://github.com/axios/axios

axios和接下来的fetch都是promise写法,所以要对promise有一定的了解。

5.3.1 GET请求
axios.get(url[, config])
//GET 请求
axios.get('/axios-server', {
    //url 参数
    params: {
        id: 100,
        vip: 7
    },
    //请求头信息
    headers: {
        name: 'atguigu',
        age: 20
    }
}).then(value => {
    console.log(value);
});
5.3.2 POST请求
axios.post(url[, data[, config]])
axios.post('/axios-server', {
    username: 'admin',
    password: 'admin'
}, {
    //url 
    params: {
        id: 200,
        vip: 9
    },
    //请求头参数
    headers: {
        height: 180,
        weight: 180,
    }
});
5.3.3 通用方法
axios(config)
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.status);
        //响应状态字符串
        console.log(response.statusText);
        //响应头信息
        console.log(response.headers);
        //响应体
        console.log(response.data);
    })
}

5.4 fetch

5.4.1 关于fetch
  • Fetch API提供了一个 JavaScript 接口,用于访问和操纵 HTTP 管道的一些具体部分,例如请求和响应。
  • 它还提供了一个全局 fetch() 方法,该方法提供了一种简单,合理的方式来跨网络异步获取资源。
  • 这种功能以前是使用 XMLHttpRequest 实现的。Fetch 提供了一个更理想的替代方案,可以很容易地被其他技术使用,例如 Service Workers

学习网站:https://developer.mozilla.org/zh-CN/docs/Web/API/Fetch_API/Using_Fetch

5.4.2 基本使用

fetch() 接受两个参数,第一个为URL,第二个是可选参数,一个可以控制不同配置的 init 对象

fetch(URL[, init])
fetch('http://127.0.0.1:8000/fetch-server?vip=10', {
    //请求方法
    method: 'POST',
    //请求头
    headers: {
        name:'atguigu'
    },
    //请求体
    body: 'username=admin&password=admin'
}).then(response => {
    // return response.text();
    return response.json();
}).then(response=>{
    console.log(response);
});

六 关于跨域

6.1 同源策略

  • 同源策略(Same-Origin Policy)最早由Netscape 公司提出,是浏览器的一种安全策略
  • 同源: 协议、域名、端口号必须完全相同
  • 跨域: 违背同源策略就是跨域
  • 发送AJAX请求经常会遇到跨域的问题

6.2 如何解决跨域

6.2.1 JSONP

1)JSONP 是什么
JSONP(JSON with Padding),是一个非官方的跨域解决方案,纯粹凭借程序员的聪明才智开发出来,只支持get 请求。

2)JSONP 怎么工作的?
在网页有一些标签天生具有跨域能力,比如:img link iframe script。
JSONP 就是利用script 标签的跨域能力来发送请求的。

3)JSONP 的使用

  1. 动态的创建一个script 标签
var script = document.createElement("script");
  1. 设置script 的src,设置回调函数
script.src = "http://localhost:3000/testAJAX?callback=abc";
function abc(data) {
	alert(data.name);
};
  1. 将script 添加到body 中
document.body.appendChild(script);
  1. 服务器种路由的处理
router.get("/testAJAX" , function (req , res) {
	console.log("收到请求");
	var callback = req.query.callback;
	var obj = {
		name:"孙悟空",
		age:18
	}
	res.send(callback+"("+JSON.stringify(obj)+")");
});

4)JQuery种的JSONP

<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="UTF-8">
		<title>Title</title>
	</head>
	<body>
		<button id="btn">按钮</button>
		<ul id="list"></ul>
		<script type="text/javascript" src="./jquery-1.12.3.js"></script>
		<script type="text/javascript">
			window.onload = function () {
				var btn = document.getElementById('btn')
				btn.onclick = function () {
					$.getJSON("http://api.douban.com/v2/movie/in_theaters?callback=?",function(data) {
						console.log(data);
						//获取所有的电影的条目
						var subjects = data.subjects;
						//遍历电影条目
						for(var i=0 ; i<subjects.length ; i++){
							$("#list").append("<li>"+
							subjects[i].title+"<br />"+
							"<img src=\""+subjects[i].images.large+"\" >"+
							"</li>");
						}
					});
				}
			}
		</script>
</body>
</html>
6.2.2 代理服务器

1)代理服务器是什么?

  • 由于浏览器存在同源策略,所以不能向非同源的服务器发送AJAX请求。
  • 但是服务器和服务器之间通信没有这种限制。
  • 所以可以先使浏览器向同源的服务器发送AJAX请求,再由该服务器转发给浏览器非同源的服务器。

2)代理服务器怎么工作的?

代理服务器

3)代理服务器使用

  • 通常来说,会使用nginx设置代理。

使用Nginx实现反向代理

  • 或者在前端框架中,可以通过配置config.js文件实现代理。

Vue全家桶之Vue中的ajax

6.2.3 CORS
  1. CORS 是什么?
  • CORS(Cross-Origin Resource Sharing),跨域资源共享。
  • CORS 是官方的跨域解决方案,它的特点是不需要在客户端做任何特殊的操作,完全在服务器中进行处理,支持
    get 和post 请求。
  • 跨域资源共享标准新增了一组HTTP 首部字段,允许服务器声明哪些源站通过浏览器有权限访问哪些资源。

学习网站:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS

  1. CORS 怎么工作的?
    CORS 是通过设置一个响应头来告诉浏览器,该请求允许跨域,浏览器收到该响应
    以后就会对响应放行。

  2. CORS 的使用
    主要是服务器端的设置:

router.get("/testAJAX" , function (req , res) {
	//通过res 来设置响应头,来允许跨域请求
	//res.set("Access-Control-Allow-Origin","http://127.0.0.1:3000");
	res.set("Access-Control-Allow-Origin","*");
	res.send("testAJAX 返回的响应");
});
  • 4
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
AJAX(Asynchronous JavaScript and XML)是一种用于创建交互式网页应用程序的技术。它允许在不刷新整个页面的情况下,通过异步发送HTTP请求并接收服务器返回的数据。以下是AJAX从入门到精通的一些关键知识点: 1. 基本概念:AJAX的核心概念是异步通信,它通过XMLHttpRequest对象向服务器发送请求,并处理服务器返回的数据。与传统的同步请求不同,AJAX请求能够在后台进行,不影响用户操作。 2. XMLHttpRequest对象:这是AJAX的核心对象,用于发送和接收数据。你可以使用它的open()方法指定请求的类型(GET或POST)、URL和是否异步等参数,然后使用send()方法发送请求,并通过onreadystatechange事件处理服务器返回的数据。 3. 服务器端处理:服务器端需要接收AJAX请求,并根据请求的类型和参数进行相应的处理。常见的服务器端语言有PHP、Python、Java等,你可以根据自己的需求选择合适的语言来处理AJAX请求。 4. 数据交互格式:AJAX可以使用多种数据交互格式,常见的有XML、JSON和HTML。你可以根据项目需要选择合适的数据格式来传输和解析数据。 5. 错误处理和调试:在使用AJAX时,可能会遇到网络错误、服务器错误等问题。你需要学会处理这些错误,并进行调试以找到问题所在。 6. 安全性考虑:由于AJAX请求是异步的,因此需要考虑安全性问题,如防止跨站脚本攻击(XSS)和跨站请求伪造(CSRF)。你可以通过一些安全措施来增强AJAX请求的安全性。 7. AJAX框架和库:除了原生的AJAX技术,还有一些流行的AJAX框架和库,如jQuery、Vue.js、React等。它们可以简化AJAX开发过程,提供更便捷的API和功能。 以上是AJAX从入门到精通的一些关键知识点,希望能帮助你更好地理解和应用AJAX技术。如果你有具体的问题或需要更深入的学习资料,可以告诉我。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值