目录
3.对URL中的参数进行解析和格式化querty string parameters
一、前置知识
1.浏览器的调试面板中额network(网络)选项
记录发送的请求
2.headers
单击其中任意一个请求
右侧header中的response header是响应头,request header是请求头,记录请求的信息
3.对URL中的参数进行解析和格式化querty string parameters
4.其他的选项
preview 响应预览
response 响应
initiator 请求链
timing 请求时长
cookie 浏览后的信息存储文件
5.拥有服务端
如果没有服务端就需要搭建一个简单服务端,可以使用express框架快速创建
(1)第一步
第一种,输入npm init 然后会要求输入一些配置项
根据官网规则更改即可
第二种,也可以直接用默认
npm init --yes
(2)第二步
使用命令安装依赖
npm install express --save
安装成功
(3)第三步
创建一个简单的服务端
在node_modules的同等级目录中创建文件夹Ajax_express,并创建文件express.js服务端文件
在express.js中引入express模块,并配置规则
//1.引入express
const express = require('express');
//2.创建应用对象
const app = express();
// 定义一个端口
const port=3000;
// 3.创建路由规则
// request是对请求报文的封装
// response是对响应报文的封装
app.get('/',(request,response)=>{
// 设置响应
response.send('HELLO express');
});
// 4.监听端口服务
app.listen(port,()=>{
console.log("服务已经启动,"+port+"端口监听中...");
})
在终端中打开进入该文件的文件夹中,启动服务
在地址栏进入这个3000端口,并回车,说明服务搭建成功
此时回到命令行,Ctrl+c停止服务
再次刷新就无法进入这个端口,我们就再配置一个自动重启服务的插件
使用nodemon插件
全局安装 npm i -g nodemon,
如果已安装可以使用npm list -g --depth命令查看npm安装的所有包
使用时发现报错
win+r输入powershell进入这个Windows工具,要以管理员运行
输入下列代码,修改执行策略
set-executionpolicy remotesigned
然后再次执行nodemon
成功,当js代码修改被保存是自动重启服务
至此就准备完成
二、利用Ajax发送请求
1.GET请求(原生)
(1)准备前端页面,需求:点击按钮发送请求
<h1>get请求</h1>
<hr />
<button>点击发送请求获取数据</button>
<div id="result"></div>
(2)准备服务端,定义server.js文件,用于向前端响应数据
//1.引入express
const express = require('express');
//2.创建应用对象
const app = express();
const port=3000;
// 3.创建路由规则
// request是对请求报文的封装;response是对响应报文的封装
//创建get规则
app.get('/server',(request,response)=>{
// 设置响应头,设置允许跨域
response.setHeader('Access-Control-Allow-Origin','*');
// 设置响应体
response.send('HELLO ajax GET');
});
// 4.监听端口服务
app.listen(port,()=>{
console.log("服务已经启动,"+port+"端口监听中...");
})
当使用nodemon启动服务后,端口已被占用,如果其他服务端启动这个端口,则需要先关闭当前端口;
代码中 '/server' 是请求数据的URL后缀
(3)定义前端js代码,发送get请求
//获取元素
const btn = document.querySelector("button");
const result = document.getElementById("result");
// 绑定鼠标单击事件
btn.onclick = function () {
// 1.创建对象
const xhr = new XMLHttpRequest();
// 2.初始化,设置请求方法和URL
// 传递参数
xhr.open("GET", "http://127.0.0.1:3000/server?a=100&b=200&c=300");
// 3.发送
xhr.send();
// 4.事件绑定,处理服务端返回的结果
//on 当.....时候
// ready state 是xhr对象中的一个属性,
//有五个值,表示状态,0未初始化;1表示open已经调用完毕
//2表示send方法调用完毕;3表示服务端返回部分结果;
//4返回所有结果
//change 改变;即改变的时候触发,这里五个值,会触发四次
xhr.onreadystatechange = function () {
// 判断服务端返回了所有的结果
if (xhr.readyState === 4) {
// 判断响应响应状态码
if (xhr.status >= 200 && xhr.status < 300) {
// 处理响应结果 行,头 ,空行,体
// 响应行
// console.log(xhr.status); //状态码
// console.log(xhr.statusText); //状态字符串
// console.log(xhr.getAllResponseHeaders()); //所有响应头
// console.log(xhr.response); //响应体
//设置div的文本
result.innerHTML = xhr.response;
} else {
}
}
};
};
传递参数
启动服务
点击按钮获取结果
2.POST请求(原生)
(1)创建服务端的规则
app.post('/server',(request,response)=>{
// (*)号表示所有类型头的信息都可以接受
response.setHeader('Access-Control-Allow-Origin','*');
// 设置响应体
response.send('HELLO ajax POST');
});
(2)定义前端代码
<body>
<h2>POST请求</h2>
<hr />
<h2>鼠标经过发送请求</h2>
<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:3000/server");
// 设置请求头,
//可以自定义请求头,不是预定义(服务端需要修改)
// xhr.setRequestHeader("name", "atg");
xhr.setRequestHeader(
"Content-Type", // Content-Type用来设置请求体内容的类型
// application / x - www - form - urlencoded用来参数查询字符串的类型;
"application/x-www-form-urlencoded"
);
// 3.发送,设置请求体
// xhr.send();可以设置请求参数
xhr.send("a:100&c:300");
// 4.事件绑定
xhr.onreadystatechange = function () {
// 判断
if (xhr.readyState === 4) {
if (xhr.status >= 200 && xhr.status < 300) {
// 处理服务端返回的结果
result.innerHTML = xhr.response;
}
}
};
});
</script>
</body>
效果如下
3.处理josn数据
(1)服务端定义一个all,可以接受任意请求
//接受任意类型的请求
app.all('/json-server',(request,response)=>{
response.setHeader('Access-Control-Allow-Origin','*');
// 设置特殊的响应头,对应前端的自定义请求头的方法,同时规则要改为all
// (*)号表示所有类型头的信息都可以接受
// response.setHeader('Access-Control-Allow-Header','*');
// 响应一个数据,例如一个对象
const data ={
name:"name"
};
//对对象进行字符串转换
let str = JSON.stringify(data);
// 设置响应体,send方法参数必须是字符串类型
response.send(str);
});
send方法只接受字符串和buffer类型(node中的类型,以二进制的形式存储),
(2)前端页面
<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:3000/json-server");
// 发送
xhr.send();
//事件绑定
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status >= 200 && xhr.status < 300) {
// console.log(xhr.response);
// result.innerHTML = xhr.response;
// 服务器返回的response是一个字符串,
// 手动转换为字符串
// let data = JSON.parse(xhr.response);
// console.log(data);
// result.innerHTML = xhr.response;
//自动转换,借助xhr对象上的一个属性
result.innerHTML = xhr.response.name;
}
}
};
};
</script>
</body>
当注释掉 xhr.responseType = "json";自动转换时, console.log(xhr.response); 将返回一个字符串
当使用 xhr.responseType = "json";自动转换时,返回一个对象格式
responseType是XMLHttpRequest对象自带的一个属性
4.请求超时以及取消请求
(1)服务端定义一个延时响应
为了方便前端问题触发,服务端定义一个3秒以后返回响应
// 延时响应
app.get('/delay',(request,response)=>{
// 设置响应头,设置允许跨域
response.setHeader('Access-Control-Allow-Origin','*');
setTimeout(() => {
// 设置响应体
response.send('延时响应');
}, (3000));
(2)前端代码
<body>
<button>点击发送请求</button>
<div id="result"></div>
<script>
// 网络超时情况是不可避免的
// 获取元素;
const result = document.getElementById("result");
const btn = document.querySelector("button");
btn.addEventListener("click", function () {
//发送请求
const xhr = new XMLHttpRequest();
// timeout属性,用于超时设置,2s内没有结果请求就取消
xhr.timeout = 2000;
//超时回调
xhr.ontimeout = function () {
alert("网络异常,请重试");
};
// 网络异常回调
xhr.onerror = function () {
alert("您的网络似乎出了一些问题");
};
//初始化
xhr.open("GET", "http://127.0.0.1:3000/delay");
// 发送
xhr.send();
//事件绑定
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status >= 200 && xhr.status < 300) {
result.innerHTML = xhr.response;
}
}
};
});
</script>
</body>
timeout属性,用于超时设置,2s内没有结果请求就取消,并触发回调 xhr.ontimeout;
当关闭服务端时,就会触发网络异常回调, xhr.onerror
(3)取消请求
前端代码
<body>
<button>点击发送</button>
<button>点击取消发送</button>
<script>
// 获取元素
const faces = document.querySelectorAll("button");
// 由于x需要在两个事件绑定中使用,所以定义为全局变量
let x = null;
faces[0].onclick = function () {
x = new XMLHttpRequest();
x.open("GET", "http://127.0.0.1:3000/delay");
x.send();
};
//abort,手动取消Ajax请求
faces[1].onclick = function () {
x.abort();
};
</script>
</body>
发送请求后,后端会在三秒以后返回结果,若在3秒前点击取消发送,则服务端不会将响应体返回。
5.解决请求重复发送的问题
请求重复发送会造成拥堵
(1)前端代码
<body>
<button>点击发送</button>
<script>
// 获取元素
const faces = document.querySelectorAll("button");
// 由于x需要在两个事件绑定中使用,所以定义为全局变量
let x = null;
//定义一个标识变量
let flag = false; //是否正在发送请求
faces[0].onclick = function () {
if (flag) x.abort(); //如果正在发送则取消该请求,发送新请求
x = new XMLHttpRequest();
// 修稿标识变量的值
flag = true;
x.open("GET", "http://127.0.0.1:3000/delay");
x.send();
x.onreadystatechange = function () {
if (x.readyState === 4) {
//在这里修改flag无论请求是否成功,都会修改,防止出现请求失败无法更改的问题
// 修改标识变量
flag = false;
}
};
};
</script>
</body>
当用户点击发送请求时, 触发 if (flag) x.abort(); 判断标记是否在发送,初始化时为false,没有在发送,即点flag值为false,不执行取消请求的操作,往下执行,创建请求后改变flag值为true
当用户连续点击发送请求时, 即一秒点击多次,由于服务端在三秒后返回响应,flag值为true,就会触发f (flag) x.abort(); 就会取消后续的请求,知道三秒后,服务端返回结果,状态码改为四,flag值则重新变为false,此时再次点击请求就会再次发送。
(2)服务端代码
// 延时响应
app.get('/delay',(request,response)=>{
// 设置响应头,设置允许跨域
response.setHeader('Access-Control-Allow-Origin','*');
setTimeout(() => {
// 设置响应体
response.send('延时响应');
}, (3000));
三、利用axios发送请求
1.axios简介
axios是一个工具包,可以在node.js中发送请求,支持promise,拥有拦截器机制,数据转换,取消请求,自动转换为json等
2.使用axios
可以通过axios教程文档使用
(1)安装
第一种,通过npm
npm install axios
第二种,在线引入,官方文档
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
第二种方式可以去bootcdn官方库国内在线引入,比上方代码速度更快
(2)准备好服务端代码
app.all('/axios-server',(request,response)=>{
// 设置响应头,设置允许跨域
response.setHeader('Access-Control-Allow-Origin','*');
// 响应一个数据,例如一个对象
const data ={
name:"张三"
};
//对对象进行字符串转换
let str = JSON.stringify(data);
// 设置响应体,send方法参数必须是字符串类型
response.send(str);
});
(3)前端代码
<!-- 引入在线的axios -->
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<body>
<button>GET</button>
<button>POST</button>
<script>
//*通过then处理返回结果
const butBox = document.querySelectorAll("button");
// 外部配置baseURL,简化链接,这是一个前缀
axios.defaults.baseURL = "http://127.0.0.1:8000";
butBox[0].onclick = function () {
// get请求
axios
.get("/axios-server", {
// 添加URL参数
params: {
id: 100,
vip: 7,
},
// 设置请求头信息
Headers: {
name: "today",
age: 20,
},
})
.then((value) => {
console.log(value.data.name);
});
};
// post请求
butBox[1].onclick = function () {
// post请求
axios
.post(
"/axios-server"
)
.then((value) => {
console.log(value);
});
};
</script>
</body>
效果如下图
get请求
post请求
3.函数的方式调用axios
前端代码
butBox.onclick = function () {
axios({
method: "get",
url: "/axios-server",
responseType: "stream",
}).then((value) => {
console.log(value);
});
};
以函数的形式调用axios,函数的参数为一个对象,内部属性可以配置请求的信息,并且获取到的返回值也很清晰,在控制台输出可以明显看到请求的大量信息
4.fetch函数的发送Ajax以及async
1.async简介
async是一种函数,声明函数,并且可以在函数中使用await表达式,await表达式可以将一个promise的返回值进行返回,async
和await
关键字让我们可以用一种更简洁的方式写出基于Promise的异步行为,而无需刻意地链式调用promise
。
async function asyncCall() {
let p= new promise();
const result = await p;
consle.log(p)
}
2.fetch函数
fetch是js自带的一个api,可以更简单的、合理的方式来跨网络异步获取资源。
语法:
Promise<Response> fetch(input[, init]);
一个简单的fetch使用,区别于axios。他传递两个参数,第一个参数是URL,第二个参数是一些基本配置项
fetch('http://example.com/movies.json')
.then(response => response.json())
.then(data => console.log(data));
具体配置项网址参考fetch官方的文档
3.fetch和async函数的使用
简单代码如下
butBox.onclick = async function () {
let p = await axios({
method: "get",
url: "/axios-server",
responseType: "stream",
});
console.log(p);
};
返回结果和之前一致
fetch函数和axios都可用于发送请求处理响应数据,两者是两种不同的方式
四、跨域
1.同源策略
出于浏览器的同源策略限制。同源策略(Sameoriginpolicy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。同源策略会阻止一个域的javascript脚本和另外一个域的内容进行交互。所谓同源(即指在同一个域)就是两个页面具有相同的协议(protocol),主机(host)和端口号(port)
————————————————
转载自CSDN博主「@Demi」的原创文章
原文链接:https://blog.csdn.net/qq_38128179/article/details/84956552
2.什么是跨域
前端页面来自于服务器的发送,当打开浏览器时输入网址,进入这个页面,即可以看到页面内容,这是服务器接受到网址请求后呈现出的结果,而在呈现页面后,通过点击或者其他交互,触发向服务器发送请求,而请求地址的URL和最初服务器页面映射的地址不同,具体指协议、端口、域名的不同,因为这三者的不同,违反了上面的同源策略,就需要对这种情况进行解决。
而解决这种问题的技术,即为跨域
3.跨域解决办法
跨域解决方式很多,详细可以参考博主「@Demi」的原创文章
这里主要记录CORS的方法
CORS是跨域资源分享(Cross-Origin Resource Sharing)的缩写。它是 W3C 标准,属于跨源 AJAX 请求的根本解决方法。
通过修改服务端配置,对请求头进行访问控制
在资料文档中有详细说明跨域资源共享(cors)文档
代码演示
前端原生Ajax发送请求
// 原生跨域
butBox.onclick = function () {
// 创建对象
const x = new XMLHttpRequest();
// 初始化设置
x.open("GET", "http://127.0.0.1:8000/cors-server");
x.send();
//绑定事件,处理响应结果
x.onreadystatechange = function () {
if (x.readyState === 4) {
if (x.status >= 200 && x.status < 300) {
// 输出响应体
console.log(x.response);
}
}
};
};
服务端
// 定义一个cors响应
app.all('/cors-server',(request,response)=>{
response.send('hello cors');
});
此时的代码是报错的,点击后提示报错
这里原因就是服务端并没有定义允许跨域
现在在服务端的代码中添加请求头允许跨域
// 定义一个cors响应
app.all('/cors-server',(request,response)=>{
// 设置允许跨域
response.setHeader("Access-Control-Allow-Origin",'*')
response.send('hello cors');
});
* 号代表允许所有网址访问时进行跨域访问,