概述
Ajax入门到精通
- 一 Ajax概述
- 1.1 Ajax简介
- 1.2 Ajax的特点
- 1.3 Ajax前置知识
- 二 两种数据交换格式
- 2.1 XML
- 2.2 JSON
- 三 HTTP相关
- 3.1 HTTP简介
- 3.2 请求报文和响应报文
- 3.3 常见响应状态码
- 四 Express搭建服务器
- 4.1 安装node.js
- 4.2 安装express(服务端框架)
- 4.3 安装nodemon自动重启工具
- 五 发送AJAX请求的4种方式
- 5.1 原生AJAX
- 5.1.1 XHR
- 5.1.2 GET和POST
- 5.1.3 JSON数据请求
- 5.1.4 IE缓存问题
- 5.1.5 超时与网络异常
- 5.1.6 重复请求问题
- 5.2 JQuery发送AJAX
- 5.2.1 GET请求
- 5.2.2 POST请求
- 5.2.3 通用方法
- 5.3 axios
- 5.3.1 GET请求
- 5.3.2 POST请求
- 5.3.3 通用方法
- 5.4 fetch
- 5.4.1 关于fetch
- 5.4.2 基本使用
- 六 关于跨域
- 6.1 同源策略
- 6.2 如何解决跨域
- 6.2.1 JSONP
- 6.2.2 代理服务器
- 6.2.3 CORS
一 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框架。
① 首先给出我的目录结构
② 初始化环境
E:completeAJAX> npm init --yes
③ 下载express包
E:completeAJAX> 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:completeAJAX代码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使用步骤
- 创建 XMLHttpRequest 对象
var xhr = new XMLHttpRequest();
- 设置请求信息
//请求准备
xhr.open(method, url);
//可以设置请求头,一般不设置
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
- 发送请求
xhr.send(body) //get 请求不传 body 参数,只有 post 请求使用
- 接收响应
//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
事件。
5.1.2 GET和POST
接下来通过两个简单的例子,说明一下GET请求和POST请求。
① 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请求参数
② POST请求
鼠标放到div中,发post请求,将响应体放在div中呈现
案例效果
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','*');
查看请求体
5.1.3 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 的使用
- 动态的创建一个script 标签
var script = document.createElement("script");
- 设置script 的src,设置回调函数
script.src = "http://localhost:3000/testAJAX?callback=abc";
function abc(data) {
alert(data.name);
};
- 将script 添加到body 中
document.body.appendChild(script);
- 服务器种路由的处理
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
- CORS 是什么?
- CORS(Cross-Origin Resource Sharing),跨域资源共享。
- CORS 是官方的跨域解决方案,它的特点是不需要在客户端做任何特殊的操作,完全在服务器中进行处理,支持
get 和post 请求。 - 跨域资源共享标准新增了一组HTTP 首部字段,允许服务器声明哪些源站通过浏览器有权限访问哪些资源。
学习网站:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS
-
CORS 怎么工作的?
CORS 是通过设置一个响应头来告诉浏览器,该请求允许跨域,浏览器收到该响应
以后就会对响应放行。 -
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 返回的响应");
});
最后
以上就是明亮鲜花为你收集整理的Ajax入门到精通的全部内容,希望文章能够帮你解决Ajax入门到精通所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复