一、Ajax简介
1、XML简介
用 XML 表示:
<student>
<name>孙悟空</name>
<age>18</age>
<gender>男</gender>
</student>
{"name":"孙悟空","age":18,"gender":"男"}
2、Ajax的特点
Ⅰ-AJAX 的优点
Ⅱ-Ajax的缺点
3、HTTP简介
Ⅰ-请求报文
Ⅱ-响应报文
Ⅲ-Chrome网络控制台查看通信报文
二、原生Ajax
〇-Ajax的使用
Ⅰ-Get方式
btn.onclick = function () {
const xhr = new XMLHttpRequest();
xhr.open('GET', 'http://127.0.0.1:8000/server?a=100&b=200&c=300');
xhr.send();
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status >= 200 && xhr.status < 300) {
result.innerHTML = xhr.response;
} else {}
}
}
}
Ⅱ-Post方式
result.addEventListener("mouseover", function(){
const xhr = new XMLHttpRequest();
xhr.open('POST', 'http://127.0.0.1:8000/server');
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
xhr.setRequestHeader('name','atguigu');
xhr.send('a=100&b=200&c=300');
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
if(xhr.status >= 200 && xhr.status < 300){
result.innerHTML = xhr.response;
}
}
}
});
Ⅲ-解决ie缓存问题
Ⅳ-请求超时与网络异常
btn.addEventListener('click', function(){
const xhr = new XMLHttpRequest();
xhr.timeout = 2000;
xhr.ontimeout = function(){
alert("网络异常, 请稍后重试!!");
}
xhr.onerror = function(){
alert("你的网络似乎出了一些问题!");
}
xhr.open("GET",'http://127.0.0.1:8000/delay');
xhr.send();
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
if(xhr.status >= 200 && xhr.status< 300){
result.innerHTML = xhr.response;
}
}
}
})
Ⅴ-取消请求
const btns = document.querySelectorAll('button');
let x = null;
btns[0].onclick = function(){
x = new XMLHttpRequest();
x.open("GET",'http://127.0.0.1:8000/delay');
x.send();
}
btns[1].onclick = function(){
x.abort();
}
Ⅵ-重复请求问题
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;
}
}
}
三、常见三种Ajax请求方式
1、jQuery发送AJAX请求
Ⅰ-$.get()
$('button').eq(0).click(function(){
$.get('http://127.0.0.1:8000/jquery-server', {a:100, b:200}, function(data){
console.log(data);
},'json');
});
Ⅱ-$.post()
$('button').eq(1).click(function(){
$.post('http://127.0.0.1:8000/jquery-server', {a:100, b:200}, function(data){
console.log(data);
});
});
Ⅲ-$.ajax
$('button').eq(2).click(function(){
$.ajax({
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
}
});
});
2、Axios发送AJAX请求
Ⅰ-axios.get()
axios.defaults.baseURL = 'http://127.0.0.1:8000';
btns[0].onclick = function () {
axios.get('/axios-server', {
params: {
id: 100,
vip: 7
},
headers: {
name: 'atguigu',
age: 20
}
}).then(value => {
console.log(value);
});
}
Ⅱ-axios.get()
axios.defaults.baseURL = 'http://127.0.0.1:8000';
btns[1].onclick = function () {
axios.post('/axios-server', {
username: 'admin',
password: 'admin'
}, {
params: {
id: 200,
vip: 9
},
headers: {
height: 180,
weight: 180,
}
});
}
Ⅲ-axios() 常用
axios.defaults.baseURL = 'http://127.0.0.1:8000';
btns[2].onclick = function () {
axios({
method: 'POST',
url: '/axios-server',
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);
})
}
3、Fetch发送AJAX请求
btn.onclick = function () {
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.json();
}).then(response => {
console.log(response);
});
}
四、跨域与解决
1、jsonP
Ⅰ-jsonP的使用
var script = document.createElement("script");
script.src = "http://localhost:3000/testAJAX?callback=abc";
function abc(data) {
alert(data.name);
};
document.body.appendChild(script);
router.get("/testAJAX", function (req, res) {
console.log("收到请求");
var callback = req.query.callback;
var obj = {
ame: "孙悟空",
age: 18
}
res.send(callback + "(" + JSON.stringify(obj) + ")");
});
Ⅱ-jQuery发送jsonP请求
$('button').eq(0).click(function () {
$.getJSON('http://127.0.0.1:8000/jquery-jsonp-server?callback=?', function (data) {
$('#result').html(`
名称: ${data.name}<br>
校区: ${data.city}
`)
});
});
app.all('/jquery-jsonp-server', (request, response) => {
const data = {
name: '尚硅谷',
city: ['北京', '上海', '深圳']
};
let str = JSON.stringify(data);
let cb = request.query.callback;
response.end(`${cb}(${str})`);
});
Ⅲ-开发封装的jsonP插件
let test=function () {
jsonP.req({
url:"http://localhost:3000/jsonpx",
data:{
a:"111"
},
callback:function (result) {
alert("成功"+result)
}
})
}
router.get('/jsonpx', async function (req, resp, next) {
let callback=req.query.callback;
let data=req.query.a;
if (!data){
resp.send(`${callback}('洪jl:我是服务端代码')`)
}
resp.send(`${callback}('洪jl:我是服务端代码`+data+`')`)
})
<script>
let jsonP = {};
jsonP.char = {
Number: '0123456789',
Letter: 'qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM'
}
jsonP.newFunId = function (charLen, numLen) {
let id = '';
for (let i = 0; i < charLen; i++) {
id += this.char.Letter.charAt(Math.random() * 52)
}
for (let j = 0; j < numLen; j++) {
id += Math.floor(Math.random() * 10);
}
return id;
}
jsonP.jointUrl = function (url, key, value) {
if (url && key && value) {
let sign = "&"
if (url.indexOf('?') == -1) {
sign = '?'
}
url += sign + key + "=" + value
}
return url;
}
jsonP.err = function (msg) {
console.error(msg)
}
jsonP.req = function (options) {
let jsonId={};
jsonId.funId = this.newFunId(4,8);
let Userurl = options.url;
let Userdata = options.data;
if (!options) {
this.err("输入不能空")
return;
} else if (!Userurl) {
this.err("url不能空")
return;
} else if (!Userdata) {
Userdata = {};
}
Userdata.callback = jsonId.funId;
for (let key in Userdata) {
Userurl = this.jointUrl(Userurl, key, Userdata[key])
}
let script = document.createElement('script');
script.setAttribute("id" , jsonId.funId);
script.setAttribute("src" , Userurl);
let callback=function (result) {
console.log("xxxxxxx")
if (options.callback){
try {
options.callback(result)
}catch (e) {
this.err(e.message)
}
}
let tmp=document.getElementById(jsonId.funId)
tmp.parentNode.removeChild(tmp);
eval(jsonId.funId+'=null')
}
eval("window."+jsonId.funId+"=function(result){ callback(result) }")
document.head.appendChild(script)
}
</script>
2、CORS
Ⅰ-代码示例
app.all('/cors-server', (request, response) => {
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Headers", '*');
response.setHeader("Access-Control-Allow-Method", '*');
response.send('hello CORS');
});
Ⅱ-HTTP 响应首部字段
1、Access-Control-Allow-Origin
2、Access-Control-Expose-Headers
3、Access-Control-Max-Age
4、Access-Control-Allow-Credentials
5、Access-Control-Allow-Methods
6、Access-Control-Allow-Headers
Ⅲ-HTTP 请求首部字段
1、Origin
2、Access-Control-Request-Method
3、Access-Control-Request-Headers
五、服务端代码示例
const express = require('express');
const app = express();
app.get('/server', (request, response) => {
response.setHeader('Access-Control-Allow-Origin', '*');
response.send('HELLO AJAX - 2');
});
app.all('/server', (request, response) => {
response.setHeader('Access-Control-Allow-Origin', '*');
response.setHeader('Access-Control-Allow-Headers', '*');
response.send('HELLO AJAX POST');
});
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);
});
app.get('/ie', (request, response) => {
response.setHeader('Access-Control-Allow-Origin', '*');
response.send('HELLO IE - 5');
});
app.all('/delay', (request, response) => {
response.setHeader('Access-Control-Allow-Origin', '*');
response.setHeader('Access-Control-Allow-Headers', '*');
setTimeout(() => {
response.send('延时响应');
}, 1000)
});
app.all('/jquery-server', (request, response) => {
response.setHeader('Access-Control-Allow-Origin', '*');
response.setHeader('Access-Control-Allow-Headers', '*');
const data = {
name: '尚硅谷'
};
response.send(JSON.stringify(data));
});
app.all('/axios-server', (request, response) => {
response.setHeader('Access-Control-Allow-Origin', '*');
response.setHeader('Access-Control-Allow-Headers', '*');
const data = {
name: '尚硅谷'
};
response.send(JSON.stringify(data));
});
app.all('/fetch-server', (request, response) => {
response.setHeader('Access-Control-Allow-Origin', '*');
response.setHeader('Access-Control-Allow-Headers', '*');
const data = {
name: '尚硅谷'
};
response.send(JSON.stringify(data));
});
app.all('/jsonp-server', (request, response) => {
const data = {
name: '尚硅谷atguigu'
};
let str = JSON.stringify(data);
response.end(`handle(${str})`);
});
app.all('/check-username', (request, response) => {
const data = {
exist: 1,
msg: '用户名已经存在'
};
let str = JSON.stringify(data);
response.end(`handle(${str})`);
});
app.all('/jquery-jsonp-server', (request, response) => {
const data = {
name: '尚硅谷',
city: ['北京', '上海', '深圳']
};
let str = JSON.stringify(data);
let cb = request.query.callback;
response.end(`${cb}(${str})`);
});
app.all('/cors-server', (request, response) => {
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Headers", '*');
response.setHeader("Access-Control-Allow-Method", '*');
response.send('hello CORS');
});
app.listen(8000, () => {
console.log("服务已经启动, 8000 端口监听中....");
});