赞
踩
大家好~ 今天写份笔记 记录一下学了2天的AJAX 并对知识进行梳
在这篇文章中,我将介绍AJAX基础知识、HTTP协议相关 AJAX相关工具、AJAX的简单使用方法 、AJAX的超时与网络异常、利用axios函数和fetch函数发送异步请求、解决跨域问题的策略等.
学习AJAX需要具备一定的HTTP协议知识 我简略的叙述一下
HTTP协议分为 客户端请求消息(请求) 与 服务器响应消息(响应) 两部分
请求格式:
请求行: get(post)/url/httpVersion
请求头: Host、Cookie、Content-type、User-Agent(格式为键值对)
空行
请求体
需要注意的是 在get请求,请求体只能为空 在post请求中,请求体中可以不为空
响应格式:
行:HTTPVerison/响应状态码(200)/响应状态字符串(ok)
头:Content-type:text/hmcl;charset=utf-8 Content-length:2048
空行
响应体
需要注意的是响应报文中的响应体一般都是一个html文件<html>...<html/>
VSCODE直接下载 Visual Studio Code - Code Editing. Redefined
安装node.js 下载 | Node.js 中文网 选择合适自己计算机的安装包下载
接下来安装express
此时就安装成功了
直接在终端上输入回车即可
npm install -g nodemon
准备工作已经完成 接下来就是具体的AJAX操作方法
客户端使用AJAX发送请求的四大步骤
GET方法实例
- {
- // 进行ajax操作
- // 1 创建对象
- const xhr = new XMLHttpRequest();
-
- // 2 初始化 设置请求方法和url
- // xhr.open('GET', 'http://127.0.0.1:8000/server');
- // 可以对url进行追加参数
- // xhr.open('GET', 'http://127.0.0.1:8000/server?a=100&b=200&c=300');
-
- // 3 发送
- xhr.send();
-
- // 4 绑定事件 处理服务端返回的结果
- // readystate是xhr的属性,有0(初始化)、1(open)、2(send)
- // 3(服务端返回部分结果)、4(服务端返回所有结果)五个值
- xhr.onreadystatechange = function () {
- // 此函数要触发4次,每次改变状态的时候会触发 因此要判断状态
- // 若返回所有的结果
- if (xhr.readyState == 4) {
- // 响应状态码为ok时 处理数据
- if (xhr.status >= 200 && xhr.status <= 300) {
- // 响应行 响应头
- // 控制台中显示请求报文的相关信息和响应报文
- console.log(xhr.status);
- console.log(xhr.statusText);
- console.log(xhr.getAllResponseHeaders());
- console.log(xhr.response);
- // 点击按钮,从服务端获取数据就大功告成了!
- }
-
- }
- }
- }
POST方法实例
- {
- const xhr = new XMLHttpRequest();
- xhr.open('POST', 'http://127.0.0.1:8000/server');
- // --------------------------
- // 设置请求头 接收键值对
- // xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
- // Content - type 设置请求体的类型
- // 自定义头信息可以设置 但浏览器会报错
- // xhr.setRequestHeader('name', 'Jess');
- // --------------------------------- 以上东西有风险
-
- // POST可以设置请求体,包含请求参数
- xhr.send('a=100&b=200&c=300');
- // xhr.send('a:100&b:200&c:300');
- // xhr.send('1234567890');
- xhr.onreadystatechange = () => {
- if (xhr.readyState == 4) {
- if (xhr.status >= 200 && xhr.status <= 300) {
- result.innerHTML = xhr.response;
- }
- }
- }
- }
服务端对请求做出响应
-
- const { request } = require('express');
- const { response } = require('express');
- const { application } = require('express');
- const { json } = require('express/lib/response');
-
- // ----------------------------------
- // 1 引入express(有了这句会生成上面的4行代码)
- const express = require('express');
- // ----------------------------------
-
-
- // ----------------------------------
- // 2 创建应用对象
- const app = express();
- // ----------------------------------
-
- // ----------------------------------
- // 3 创建路由规则
- // 创建路由规则 请求报文和响应报文 get请求和post请求的路由规则不同
- // ----------------------------------
-
- // server作为url 响应在客户端对应的url
- app.get('/server',(request,response)=>{
- // 设置响应头,允许跨域
- response.setHeader('Access-Control-Allow-Origin','*');
- // 设置响应
- // 此处尽情发挥
- response.send('Hello-RESPONSE-AJAX');
- })
-
- // post这里实际上不能运行,因为在客户端已经自定义了请求头
- app.post('/server',(request,response)=>{
- // 设置响应头,允许跨域
- response.setHeader('Access-Control-Allow-Origin','*');
- // 设置允许接收所有类型的请求头 但此时浏览器还有一个OPTION类型的请求进行校验 将post改为all即可
- response.setHeader('Access-Control-Allow-Header','*')
- // 设置响应体
- response.send('Hello AJAXPOST');
- })
-
- // 应该用all方法来处理POST中设置自定义的请求头
- app.all('/server',(request,response)=>{
- // 设置响应头,允许跨域
- response.setHeader('Access-Control-Allow-Origin','*');
- // 设置允许接收所有类型的请求头 但此时浏览器还有一个OPTION类型的请求进行校验 将post改为all即可
- response.setHeader('Access-Control-Allow-Headers','*');
- // 设置响应体
- response.send('HelloAJAXPOSTDeam');
- })
-
- // 8000是一个端口,开启服务的时候占的端口号(可自定义)
- app.listen(8000,()=>{
- console.log("服务已启动,端口8000正在监听......");
- })
- 重复发送请求
- 设置一个标志,记录是否已经发送请求,如果是,则取消当前请求并重新发送请求
- // 解决重复发送请求问题 降低服务器压力
- {
- let isSending = false;
- if (isSending) {
- xhr.abort();
- }
- const xhr = new XMLHttpRequest();
- isSending = true;
-
- // 超时设置
- xhr.timeout = 2000;
-
- // 超时回调
- xhr.ontimeout = () => {
- alert('发送超时!请稍后重试')
- }
-
- // 网络异常
- xhr.onerror = () => {
- alert('网络异常');
- }
-
- xhr.open('GET', 'http://127.0.0.1:8000/server');
- xhr.send();
- xhr.onreadystatechange = () => {
- if (xhr.readyState == 4) {
- isSending = false;
- }
- }
- });
AXIOS是Vue 和 React 推荐的AJAX API 官方文档 : axios中文网|axios API 中文文档 | axios
用script标签引入即可使用
<script crossorigin="anonymous" src="https://cdn.bootcdn.net/ajax/libs/axios/0.27.2/axios.js"></script>
- <!DOCTYPE html>
- <html lang="en">
-
- <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>Document</title>
- <!-- <script src="https://unpkg.com/axios/dist/axios.min.js"></script> -->
- <script crossorigin="anonymous" src="https://cdn.bootcdn.net/ajax/libs/axios/0.27.2/axios.js"></script>
-
- </head>
-
- <body>
- <button>GET</button>
- <button>POST</button>
- <button>AXIOS</button>
-
- <script>
- const btn = document.querySelectorAll('button');
- // get方法 url用'' 导入
- // 创建axios实例
- btn[0].onclick = function () {
- axios.get('http://127.0.0.1:8000/axios-server', {
- params: {
- ID: 12345
- }
- })
- }
-
- // post方法第一个{}中必须是请求体,请求参数和请求头以对象的形式写入
- btn[1].onclick = function () {
- axios.post('http://127.0.0.1:8000/axios-server', {
- username: 'Jess'
- }, {
- params: {
- id: 123123
- },
- headers: {
- name: 'Jess'
- }
- });
- }
-
- // 推荐AXIOS发送请求
- // 将所有的参数都写在一起 方便快捷
- // method和url必须写出并在首位
- btn[2].onclick = function () {
- axios({
- method: 'POST',
- url: 'http://127.0.0.1:8000/axios-server',
- params: {
- id: 10,
- level: 30
- },
- headers: {
- a: 100,
- b: 200
- },
- data: {
- username: 'admin',
- pwd: 'admin'
- }
- }).then(response => {
- console.log(response.status);
- console.log(response.statusText);
- console.log(response.headers);
- // 响应体
- console.log(response.data);
- })
- }
- </script>
- </body>
-
- </html>
-
-
-
- //服务端
- //--------------------------
- // 响应axios
- app.all('/axios-server',(request,response)=>{
- // 设置响应头,允许跨域
- response.setHeader('Access-Control-Allow-Origin','*');
- // 设置允许接收所有类型的请求头 但此时浏览器还有一个OPTION类型的请求进行校验 以all即可
- response.setHeader('Access-Control-Allow-Headers','*');
- // 设置响应体
- response.send('HelloAJAXAXIOS');
- })
fetch()也可以发送AJAX请求
这里提一下,服务器发送JSON对象
- fetch('http://127.0.0.1:8000/fetch-server', {
- // 请求方法
- method: 'POST',
- // 请求头
- headers: {
- name: 'Jess'
- },
- // 请求体
- body: 'username=admin&password=admin'
- }).then(response => {
- // text是一个对response.content内容进行解码的一个函数
- // console.log(response);
- return response.text();
- // 如果返回的是一个JSON对象
- // return response.json();
- }).then(response => {
- console.log(response);
- })
-
- //服务端
- app.all('/fetch-server',(request,response)=>{
- // 设置响应头,允许跨域
- response.setHeader('Access-Control-Allow-Origin','*');
- // 设置允许接收所有类型的请求头 但此时浏览器还有一个OPTION类型的请求进行校验 以all即可
- response.setHeader('Access-Control-Allow-Headers','*');
- // 设置响应体
- response.send('HelloAJAXFETCH');
- })
同源策略(Sameoriginpolicy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响
同源需要做到 : 协议、域名、端口都要相同
在路由规则中设置响应头:
- 设置响应头,允许跨域
- response.setHeader('Access-Control-Allow-Origin','*');
JSONP 即通过script标签引用路由规则的方法
此方法最常用 但也有许多坑,需要注意服务器返回的东西需要让Javascript解析因此不能乱传数据.
- <body>
- 用户名:<input type="text" id="username">
- <p></p>
- <script>
- const input = document.getElementById('username');
-
- function handle(data) {
- const p = document.querySelector('p');
- p.innerHTML = data.msg;
- }
- input.onblur = function () {
- let uname = this.value;
- // 发送请求
- const script = document.createElement('script');
- script.src = 'http://127.0.0.1:8000/check-server';
- // 在body中追加script节点
- document.body.append(script);
- }
- </script>
- </body>
-
-
- app.all('/JSONP-server',(request,response)=>{
- // jsonp就是利用script标签不受同源策略限制的这一点,通过get的方式执行后端返回的js脚本
- // 重点在是只能用GET方式执行
- const data ={
- name:'Jess'
- }
- let str = JSON.stringify(data);
- // 使用end函数
- // ${ }是es6新增的字符串方法,可以配合``单反引号完成字符串拼接的功能
- // 用法:(1). 定义需要拼接的字符串
- // (2). 将字符串用${ }包起来,写到需要拼接的地方
-
- // 返回结果
- response.end(`handle(${str})`);
- // 返回结果不想其他服务一样,如果用JSONP服务的话单纯返回数据 浏览器无法解析
- // 因为是引用 所有返回的数据需要Javascript解析
- // 因此需要返回JS语句或者函数等可被解析的代码
- })
写了这么多,花了2、3个小时整理,期间遇到不太理解的又重新学习一番
学时2天 将学过知识总结凝练 以供以后思考反思
希望走过路过的大佬们 指出问题 不胜感激!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。