Ajax的基本使用
# Ajax
# 1.前提知识
# 1.1 Ajax简要
AJAX = Asynchronous JavaScript and XML
(异步的 JavaScript 和 XML)
AJAX 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。
Ajax 不是一种新的编程语言,而是一种用于创建更好更快以及交互性更强的Web应用程序的技术。
在 2005 年,Google 通过其 Google Suggest 使 AJAX 变得流行起来。Google Suggest能够自动帮你完成搜索单词。
Google Suggest 使用 AJAX 创造出动态性极强的 web 界面:当您在谷歌的搜索框输入关键字时,JavaScript 会把这些字符发送到服务器,然后服务器会返回一个搜索建议的列表。
就和国内百度的搜索框一样!
传统的网页(即不用ajax技术的网页),想要更新内容或者提交一个表单,都需要重新加载整个网页。
使用ajax技术的网页,通过在后台服务器进行少量的数据交换,就可以实现异步局部更新。
使用Ajax,用户可以创建接近本地桌面应用的直接、高可用、更丰富、更动态的Web用户界面。
# 1.2 Ajax的优缺点
优点:
- 可以无需刷新页面与服务器端进行通信
- 允许你根据用户事件来更新部分页面内容
缺点:
- 没有浏览历史,不能回退
- 存在跨域的问题(同源)
- SEO不友好
# 1.3 HTTP协议概念
HTTP(hypertext transport protocol)协议超文本传输协议
,协议详细规定了浏览器和万维网服务器之间互相通信的规则
1.请求报文
request是请求报文,重要的是格式和参数
行 POST /s?ie=utf-8 HTTP/1.1
头 Host: atguigu.com
Cookie: name=guigu
Content-type: application/x-www-form-urlencoded
User-Agent: chrome 83
空行
请求体 username=admin&password=admin
2.响应报文
response是响应报文,重要是格式和参数,其会返回状态代码,分别是200、300、401、403、404、500
等。
行 HTTP/1.1 200 OK
头 Content-Type: text/html;charset=utf-8
Content-length: 2048
Content-encoding: gzip
空行
体 <html>
<head>
<body>
<h1>标题1</h1>
</body>
</head>
</html>
# 1.4 浏览器开发工具
1.按住F12
进入开发者工具,此处为查看请求头的内容。
2.查看某些响应报文内容
# 1.5 Node.js安装
官方网站:https://nodejs.org/zh-cn/ (opens new window)
# 1.6 Express开发框架
Express是基于Node.js平台的快速、开放、极简的Web开发框架。
官方网站: https://www.expressjs.com.cn/ (opens new window)
# 2.Express基本使用
1.初始化node.js依赖包
$ npm init --yes
$ npm install express --save
2.引入Express框架,创建第一个服务器
// 1. 引入express
const { response } = require('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端口监听中....");
});
3.启动服务
$ node .\Ajax基本使用01.js
4.访问端口和路径
# 3. 原生Ajax
# 3.1 Ajax案例准备
1.创建Ajax服务端
// 1.引入express
const { response, request} = require('express');
const express = require('express');
// 创建应用对象
const app = express();
// 3.创建路由规则
// request 是对请求报文的封装
// response 是对响应报文的封装
app.get('/server',(request,response)=>{
// 设置响应头 设置允许跨域
response.setHeader('Access-Control-Allow-Origin','*');
// 设置响应
response.send("Hello World");
});
// 监听端口启动服务
app.listen(8080,()=>{
console.log("服务已经启动完成,8080端口监听中...");
});
2.创建案例页面
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<style>
#result {
width: 200px;
height: 100px;
border: 1px solid red;
}
</style>
<body>
<button>发送请求</button>
<div id="result" ></div>
</body>
<script>
// 获取button的元素
const btn = document.getElementsByTagName('button')[0];
var div = document.getElementById('result');
// 绑定事件
btn.onclick = function(){
// 1.创建对象
const xhr = new XMLHttpRequest();
// 2.初始化 设置请求方法和URL
xhr.open('GET','http://localhost:8080/server');
// 3.发送
xhr.send();
// 4. 事件绑定 处理服务端返回的结果
// on when 当...的时候
// readystate 是xhr对象中的属性,表示状态 0 1 2 3 4
// change 改变
xhr.onreadystatechange = function(){
// 判断 (服务端返回了所有的结果)
if(xhr.readyState === 4){
// 判断响应状态码 200 404 403 401 500
// 2xx 成功
if(xhr.status >= 200 && xhr.status < 300){
// 处理结果 行 头 空行 体
// 1. 响应行
console.log(xhr.status); // 状态码
console.log(xhr.statusText); // 状态字符串
console.log(xhr.getAllResponseHeaders()); // 所有响应头
console.log(xhr.response); // 响应体
div.innerHTML = xhr.response;
}else{
}
}
}
}
</script>
</html>
3.查看访问的结果
# 3.2 发送GET请求
发送GET请求的参数一般使用?a=var&b=var
的追加方式。
btn.onclick = function(){
// 1.创建对象
const xhr = new XMLHttpRequest();
// 2.初始化 设置请求方法和URL
xhr.open('GET','http://localhost:8080/server?a=100&b=200&c=300');
// 3.发送
xhr.send();
# 3.3 发送POST请求
post请求需要设置请求体,在send()方法里面设置请求体。
send('a=100&b=100&c=300');
send('a:100&b:100&c:300');
1.Ajax需要添加一个post请求
app.post('/server',(request,response)=>{
// 设置响应头 设置允许跨域
response.setHeader('Access-Control-Allow-Origin','*');
// 设置响应
response.send("Hello World POST");
});
2.创建一个测试页面
这里的获取元素的方式抛弃DOM的对象,使用JQuery的对象。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
#result{
width: 200px;
height: 100px;
border: solid 1px red;
}
</style>
</head>
<script src="https://code.jquery.com/jquery-3.6.1.min.js" type="text/javascript" charset="UTF-8"></script>
<body>
<div id="result"></div>
<script>
// 获取元素对象
$(function (){
$("#result").on("mouseover",function (){
// 1.创建对象
const xhr = new XMLHttpRequest();
// 2.初始化 设置类型与 URL
xhr.open('POST','http://localhost:8080/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){
// 处理服务端返回的结果
var response = xhr.response;
$("#result").html(" "+ response +" ");
}
}
}
})
})
</script>
</body>
</html>
3.访问页面查看请求体
# 3.4 设置请求头
一般设置请求 头的内容有预定义和自定义两种方式。
预定义的有:
Host
: atguigu.comCookie
: name=guiguContent-type
: application/x-www-form-urlencodedUser-Agent
: chrome 83
自定义的:
- name: admin
- type: html
1.Ajax添加一个可以接收任意的请求
// 设置可以接收任意类型的请求
app.all('/server',(request,response)=>{
// 设置响应头 设置允许跨域
response.setHeader('Access-Control-Allow-Origin','*');
// 设置响应头
response.setHeader('Access-Control-Allow-Headers','*');
// 设置响应
response.send("Hello World POST");
});
2.发送一个请求头的类型和自定义的类型
<script>
// 获取元素对象
$(function (){
$("#result").on("mouseover",function (){
// 1.创建对象
const xhr = new XMLHttpRequest();
// 2.初始化 设置类型与 URL
xhr.open('POST','http://localhost:8080/server');
// 设置请求头 application/x-www-form-urlencoded
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
xhr.setRequestHeader('name','admin');
// 3.发送
xhr.send('a=100&b=200&c=300');
})
})
</script>
# 3.5 服务端响应JSON
Ajax的服务端响应JSON的数据,有三种方式可以接受或者响应JSON的数据,分别是:
- 直接接受json的数据
- 手动对数据的转换
- 自动对数据的转换
1.Ajax添加任意请求的方式,添加一个对象,这个对象需要转换成字符串的方式。
// 设置可以接收任意类型的请求
app.all('/json-server',(request,response)=>{
// 设置响应头 设置允许跨域
response.setHeader('Access-Control-Allow-Origin','*');
// 设置响应头
response.setHeader('Access-Control-Allow-Headers','*');
// 响应一个数据
const data = {
name: 'user1',
age: 18
}
// 对对象进行字符串的转换
let str = JSON.stringify(data);
// 设置响应
response.send(str);
});
2.使用三种方式获取json的数据
- 手动对数据的转换:
let data = JSON.parse(xhr.response);
- 自动对数据的转换:
xhr.responseType = 'json';
<script>
// 获取元素对象
$(function (){
$("#result").on("mouseover",function (){
// 1.创建对象
const xhr = new XMLHttpRequest();
xhr.responseType = 'json';
// 2.初始化 设置类型与 URL
xhr.open('GET','http://localhost:8080/json-server');
// 3.发送
xhr.send();
// 4.事件绑定
xhr.onreadystatechange = function (){
// 判断
if(xhr.readyState === 4){
if(xhr.status >= 200 && xhr.status <= 300){
// 1.接收JSON的数据
// let data = xhr.response;
// console.log(data);
// $("#result").html(" "+ data +" ");
// 2.手动对数据的转换
// let data = JSON.parse(xhr.response);
// $("#result").html(" "+ data.name + "," + data.age +" ");
// 3.自动对数据的转换
var response = xhr.response;
console.log(response);
$("#result").html(" "+ response.name +" ");
}
}
}
})
})
</script>
# 3.6 自动重启工具
节点监视器(nodemon)
nodemon 是一个工具,它通过在检测到目录中的文件更改时自动重新启动节点应用程序来帮助开发基于 Node.js 的应用程序。
nodemon 不需要对您的代码或开发方法进行任何额外的更改。nodemon 是node
. 要使用,请在执行脚本时nodemon
替换命令行上的单词。node
安装
$ npm install -g nodemon
并且 nodemon 将全局安装到您的系统路径。
您还可以安装 nodemon 作为开发依赖项:
$ npm install --save-dev nodemon
测试
使用nodemon启动如下:
# 3.7 IE缓存问题
IE的浏览器会有缓存的问题。
<script>
// 获取元素对象
$(function (){
$("#result").on("mouseover",function (){
// 1.创建对象
const xhr = new XMLHttpRequest();
xhr.responseType = 'json';
// 2.初始化 设置IE缓存的问题 添加上时间戳
xhr.open('GET','http://localhost:8080/ie?t=' + Date.now());
// 3.发送
xhr.send();
// 4.事件绑定
xhr.onreadystatechange = function (){
// 判断
if(xhr.readyState === 4){
if(xhr.status >= 200 && xhr.status <= 300){
var response = xhr.response;
console.log(response);
$("#result").html(" "+ response.name +" ");
}
}
}
})
})
</script>
# 3.8 请求超时和异常
用户给服务器发送强求,但服务器有时候不及时响应,或者存在网络异常等问题导致用户体验感下降,为了提高用户的体验感我们可以设置弹框提示。
Ajax开启超时
方法 | 说明 |
---|---|
setTimeout() | Ajax开启超时的时间 |
1.添加get请求的超时时间为3s
// 延时响应
app.get('/timeout',(request,response) => {
// 设置响应头 设置允许跨域
response.setHeader('Access-Control-Allow-Origin','*');
// 设置超时
setTimeout(()=>{
response.send('延时响应');
},3000);
});
2.测试get请求的超时和网络异常
timeout
: 超时ontimeout
: 超时回调onerror
: 网络异常
timeout属性等于一个整数,用来设置当请求发出后等待接受响应的时间。ontimeout()方法则是当等待超时后,自动执行的回调 (opens new window)方法。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
#result{
width: 200px;
height: 100px;
border: solid 1px red;
}
</style>
</head>
<script src="https://code.jquery.com/jquery-3.6.1.min.js" type="text/javascript" charset="UTF-8"></script>
<body>
<button>点击发送请求</button>
<div id="result"></div>
<script>
// 获取元素对象
$(function (){
$("button").eq(0).on("click",function (){
// 1.创建对象
const xhr = new XMLHttpRequest();
// 设置超时 2s 设置
xhr.timeout = 2000;
// 超时回调
xhr.ontimeout = function (){
alert("网络异常,请稍后重试!");
}
// 网络异常问题
xhr.onerror = function (){
alert("你的网络似乎出现了一些问题!");
}
// 2.初始化 设置类型与 URL
xhr.open('GET','http://localhost:8080/timeout');
// 3.发送
xhr.send();
// 4.事件绑定
xhr.onreadystatechange = function (){
// 判断
if(xhr.readyState === 4){
if(xhr.status >= 200 && xhr.status <= 300){
var response = xhr.response;
console.log(response);
$("#result").html(""+ response +"");
}
}
}
})
})
</script>
</body>
</html>
3.谷歌浏览器设置网络状态
# 3.9 取消请求
在请求发送过程中,服务器返回请求之前我们可以手动取消请求。可以通过请求对象的abort()
方法来取消请求。
方法 | 说明 |
---|---|
abort() | Ajax手动取消请求 |
1.Ajax添加一个get请求用于响应数据
app.get('/delay',(request,response)=>{
// 设置响应头 设置允许跨域
response.setHeader('Access-Control-Allow-Origin','*');
setTimeout(() => {
// 设置响应
response.send("Hello World");
},3000);
});
2.取消请求的html页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<script src="https://code.jquery.com/jquery-3.6.1.min.js" type="text/javascript" charset="UTF-8"></script>
<body>
<button>点击发送</button>
<button>点击取消</button>
<script>
// 获取元素
$(function (){
let x = null;
$("button").eq(0).on("click",function (){
x = new XMLHttpRequest();
x.open("GET",'http://localhost:8080/delay');
x.send();
});
// 使用abort手动取消请求
$("button").eq(1).on("click",function (){
x.abort();
})
})
</script>
</body>
</html>
# 3.10 重复请求的优化
重复请求优化,就是在多次点击提交的时候,不会造成排队的现象,每次点击提交都会阻塞之前的提交,当前的提交为重新提交。
1.Ajax的请求不需要修改,在当前的GET请求中操作。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<script src="https://code.jquery.com/jquery-3.6.1.min.js" type="text/javascript" charset="UTF-8"></script>
<body>
<button>点击发送</button>
<button>点击取消</button>
<script>
// 获取元素
$(function (){
let x = null;
// 表示变量
let isSending = false;
$("button").eq(0).on("click",function (){
// 判断标识变量 让它进行取消操作
if(isSending) x.abort();
x = new XMLHttpRequest();
// 修改表示变量
isSending = true;
x.open("GET",'http://localhost:8080/delay');
x.send();
x.onreadystatechange = function (){
if(x.readyState === 4){
// 修改表示变量
isSending = false;
}
}
});
// 使用abort手动取消请求
$("button").eq(1).on("click",function (){
x.abort();
})
})
</script>
</body>
</html>
# 4. JQuery发送Ajax请求
优秀的CDN加速JS插件: https://www.bootcdn.cn/ (opens new window)
# 4.1 JQuery方法
- JQuery发送ajax请求共有
四种
方式:通用的方式
、get
、post
、load
- 请求成功的函数返回值参数名可以自定义,异常的函数参数名是固定的
方法 | 说明 |
---|---|
$.get() | 使用JQuery发送get的Ajax请求 |
$.post() | 使用JQuery发送post的Ajax请求 |
1.创建get,post和all三个Ajax请求的,包含跨域、自定义请求头、超时
。
// 1.引入express
const { response,request } = require('express');
const express = require('express');
// 创建应用对象
const app = express();
// 创建get请求
app.get('/jquery-server',(request,response)=> {
response.setHeader('Access-Control-Allow-Origin','*');
response.setHeader('Access-Control-Allow-Headers','*');
const data = {
name: 'user'
}
response.send(JSON.stringify(data));
})
// 创建post请求
app.post('/jquery-server',(request,response)=> {
response.setHeader('Access-Control-Allow-Origin','*');
response.setHeader('Access-Control-Allow-Headers','*');
response.send('Hello AJAX JQuery');
})
// 创建all请求
app.all('/jquery-server',(request,response)=> {
response.setHeader('Access-Control-Allow-Origin','*');
response.setHeader('Access-Control-Allow-Headers','*');
const data = {
name: 'user'
}
// 此处配置超时
setTimeout(()=>{
response.send(JSON.stringify(data));
},3000);
})
// 创建监听器
app.listen(8080,()=>{
console.log('8080端口正在监听中...');
})
2.使用JQuery的方法发送Ajax请求
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>jQuery 发送 AJAX 请求</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<script crossorigin="anonymous" src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>
<body>
<div class="container">
<h2 class="page-header">jQuer发送AJAX请求</h2>
<button class="btn btn-primary">GET</button>
<button class="btn btn-danger">POST</button>
<button class="btn btn-info">通用型方法ajax</button>
</div>
<script>
$('button').eq(0).click(function (){
$.get('http://localhost:8080/jquery-server',{a:100,b:200},function (data){
console.log(data);
},'json');
})
$('button').eq(1).click(function (){
$.post('http://localhost:8080/jquery-server',{a:100,b:200},function (data){
console.log(data);
});
})
</script>
</body>
</html>
# 4.2 JQuery通用方法
方法 | 说明 |
---|---|
$.ajax() | 使用JQuery的通用方法发送Ajax请求 |
1.通用方法可以很方便的修改属性值。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>jQuery 发送 AJAX 请求</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<script crossorigin="anonymous" src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>
<body>
<div class="container">
<h2 class="page-header">jQuer发送AJAX请求</h2>
<button class="btn btn-primary">GET</button>
<button class="btn btn-danger">POST</button>
<button class="btn btn-info">通用型方法ajax</button>
</div>
<script>
// JQuery的通用方法发送Ajax请求
$('button').eq(2).click(function (){
$.ajax({
// url
url: 'http://localhost:8080/jquery-server',
// 参数
data: {a:100,b:200},
// 请求类型
type: 'GET',
// 响应体结果
dataType: 'json',
// 成功的回调
success: function (data){
console.log(data);
},
// 超时时间
timeout: 2000,
// 失败的回调
error: function (){
console.log('出错拉!');
},
headers: {
name: 'admin',
age: 18
}
})
})
</script>
</body>
</html>
# 5. Axios发送Ajax请求
Axios (opens new window)是目前最热门的Ajax工具库,使用频率比较高,是Vue和React推荐的Ajax请求的工具包。
1)vue
本身不支持发送AJAX
请求,需要使用vue-resource
、axios
等插件实现。
2) axios
是一个基于Promise
的HTTP
请求客户端,用来发送请求,也是vue2.0官方推荐的,同时不再对vue-resource
进行更新和维护。
# 5.1 Axios方法
1.Ajax添加alll类型的请求
// 创建all请求
app.all('/axios-server',(request,response)=> {
response.setHeader('Access-Control-Allow-Origin','*');
response.setHeader('Access-Control-Allow-Headers','*');
const data = {
name: 'user'
}
response.send(JSON.stringify(data));
})
2.Axios发送AJax的请求方法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<script crossorigin="anonymous" src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.0/axios.js"></script>
<script crossorigin="jquery" src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<body>
<button>GET</button>
<button>POST</button>
<button>AJAX</button>
<script>
$(function (){
// 配置baseURL
// axios.defaults.baseURI = 'http://localhost:8080';
// get请求
$("button").eq(0).on("click",function (){
// GET 请求
axios.get('http://localhost:8080/axios-server',{
// url参数
params: {
id: 100,
vip: 7
},
// 请求头信息
headers: {
name: 'Andy',
age: 20
}
// Axios是基于Promise做的数据处理
}).then(value => {
console.log(value);
});
})
// post请求
$("button").eq(1).on("click",function (){
// GET 请求
axios.post('http://localhost:8080/axios-server',{
// url参数
params: {
id: 200,
vip: 9
},
// 请求头信息
headers: {
height: 100,
weight: 100
}
// Axios是基于Promise做的数据处理
}).then(value => {
console.log(value);
});
})
})
</script>
</body>
</html>
# 5.2 Axios通用方法
Axios使用函数的方式发送Ajax的请求。
$("button").eq(2).on("click",function (){
axios({
// 请求方法
method: 'POST',
// url 请求行
url: 'http://localhost:8080/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);
// 响应状态字符串
console.log(response.statusText);
// 响应体信息
console.log(response.headers);
// 响应体
console.log(response.data);
})
})
# 5.3 Fetch发送Ajax请求
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>fetch 发送 AJAX请求</title>
</head>
<body>
<button>AJAX请求</button>
<script>
const btn = document.querySelector('button');
btn.onclick = function(){
fetch('http://127.0.0.1:8000/fetch-server?vip=10', {
//请求方法
method: 'POST',
//请求头
headers: {
name: 'Nliver'
},
//请求体
body: 'username=admin&password=admin'
}).then(response => {
// console.log(response);
// return response.text();
return response.json();
}).then(response => {
console.log(response);
})
}
</script>
</body>
</html>
# 6. Ajax跨域
# 6.1 同源策略
同源策略(Same-Origin-Policy)最早是由Netscape公司提出,是浏览器的一中安全策略。
- 同源: 协议、域名、端口号 必须完全相同
- 违背同源策略就是跨域
1.创建一个Ajax的服务端
const { response } = require('express');
const express = require('express');
const app = express();
app.get('/home', (request, response)=>{
//响应一个页面
response.sendFile(__dirname + '/index.html');
});
app.get('/data', (request, response)=>{
//响应一个页面
response.send('用户数据');
});
app.listen(9000,()=>{
console.log("服务已经启动...");
})
2.页面的请求内容
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>首页</title>
</head>
<body>
<h1>Nliver</h1>
<button>点击获取用户数据</button>
<script>
const btn = document.querySelector('button');
btn.onclick = function(){
const x = new XMLHttpRequest();
//这里因为是满足同源策略的,所以url可以简写
x.open("GET",'/data');
//发送
x.send();
//
x.onreadystatechange = function () {
if (x.readyState === 4) {
if(x.status >= 200 && x.status < 300){
console.log(x.response);
}
}
}
}
</script>
</body>
</html>
# 6.2 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"
1.script的跨域方法:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>原理演示</title>
<style>
#result {
width: 300px;
height: 100px;
border: solid 1px #78a;
}
</style>
</head>
<body>
<div id="result"></div>
<script>
//处理数据
function handle(data) {
//获取 result 元素
const result = document.getElementById('result');
result.innerHTML = data.name;
}
</script>
<!-- <script src="./js/app.js"></script> -->
<!-- <script src="http://127.0.0.1:5500/%E4%BB%A3%E7%A0%81/7-AJAX%E8%B7%A8%E5%9F%9F%E9%97%AE%E9%A2%98/2-JSONP/js/app.js"></script> -->
<script src="http://127.0.0.1:8000/jsonp-server"></script>
</body>
</html>
# 6.3 JSONP跨越实现
1.原生Ajax发送jsonp请求
1.创建一个请求用于检测用户。
// 检测用户名是否存在
app.all('/check-username',(request,response)=>{
const data = {
exist: 1,
msg: '用户名已经存在'
};
// 将数据转换成字符串
let str = JSON.stringify(data);
// 返回结果
response.end(`handle(${str})`);
});
2.页面测试
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>原生JSONP 实践案例</title>
</head>
<body>
用户名: <input type="text" id="username" >
<p></p>
<script>
//获取input元素
const input = document.querySelector('input');
const p = document.querySelector('p');
//声明 handle 函数
function handle(data){
//修改边框颜色
input.style.border = "solid 1px #f00";
//修改 p 标签的提交文本
p.innerHTML = data.msg;
}
//绑定事件
input.onblur = function () {
//获取用户的输入值
let username = this.value;
//向服务端发送请求 检测用户名是否存在
//1. 创建 script 标签
const script = document.createElement('script');
//2. 设置 script 标签的src属性
script.src = 'http://127.0.0.1:8000/check-username';
//3. 将 script 插入到文档中
document.body.appendChild(script);
}
</script>
</body>
</html>
2.jQuery发送jsonp请求
1.添加AJax的all类型请求
// 创建all请求
app.all('/jsonp-server',(request,response)=> {
// response.setHeader('Access-Control-Allow-Origin','*');
// response.setHeader('Access-Control-Allow-Headers','*');
const data = {
name: 'user',
city: ['北京','上海','深圳']
}
// 将数据转换为字符串
let str = JSON.stringify(data);
// 接受callback
let cb = request.query.callback;
// 返回结果
response.end(`${cb}(${str})`);
})
2.页面请求
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>jQuery-jsonp</title>
<style>
#result {
width: 300px;
height: 100px;
border: solid 1px #089;
}
</style>
<script crossorigin="anonymous" src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>
<body>
<button>点击发送 jsonp 请求</button>
<div id="result">
</div>
<script>
$('button').eq(0).click(function(){
$.getJSON('http://127.0.0.1:8000/jquery-jsonp-server?callback=?', function(data){
// console.log(data);
$('#result').html(`
名称: ${data.name}<br />
校区: ${data.city}
`)
})
});
</script>
</body>
</html>
# 6.4 CORS
1.CORS是什么?
CORS(Cross-Origin Resource Sharing),跨域资源共享。
CORS是官方的跨域解决方案,它的特点是不需要在客户端做任何特殊的操作,完全在服务器中进行处理,支持get和post请求。跨域资源共享标准新增一组HTTP首部字段,允许服务器声明哪些源站通过浏览器有权限访问哪些资源。
2.CORS怎么工作的?
CORS是通过设置一个响应头来告诉浏览器,该请求允许跨域,浏览器收到该响应以后就会对响应放行。
3.CORS的使用
主要是服务端的设置:
app.get('/cors-server',(request,response)=>{
// 设置响应头 设置允许跨域
response.setHeader('Access-Control-Allow-Origin','*');
response.setHeader('Access-Control-Allow-Headers','*');
response.setHeader('Access-Control-Allow-Origin','http://127.0.0.1:5000');
// 设置响应
response.send("Hello World");
});