当前位置:   article > 正文

AJAX的学习笔记(复习自用,欢迎补充)_const { application } = require('ee-core');

const { application } = require('ee-core');

        大家好~ 今天写份笔记 记录一下学了2天的AJAX 并对知识进行梳

        在这篇文章中,我将介绍AJAX基础知识、HTTP协议相关 AJAX相关工具、AJAX的简单使用方法 、AJAX的超时与网络异常、利用axios函数和fetch函数发送异步请求、解决跨域问题的策略等.

AJAX基础知识

  1.  AJAX aka Asynchronous Javascript And XML. 即异步JavaScript和XML
  2.  AJAX最大优势 : 网页在不刷新的情况下向服务器发送请求,允许用户更新部分页面的内容(聪数据库中提取)
  3.  AJAX缺点 : 无浏览历史 不能回退 存在跨域问题 
  4.  AJAX依旧用JS作为语言 
  5.  异步请求有三种: 普通事件 资源加载 定时器
  6.  常见的使用场合 : 搜索栏弹出相关加载(懒加载) 检测用户名是否重名等

HTTP协议的一些相关知识 

        学习AJAX需要具备一定的HTTP协议知识 我简略的叙述一下

        HTTP协议分为 客户端请求消息(请求) 与 服务器响应消息(响应) 两部分

        请求格式:

        请求行: get(post)/url/httpVersion

        请求头:    Host、Cookie、Content-type、User-Agent(格式为键值对)

        空行

        请求体

我自己敲代码案例时的请求头 里面有自定义请求头a和b(仅作示范用)

需要注意的是 在get请求,请求体只能为空 在post请求中,请求体中可以不为空

        响应格式:

        行:HTTPVerison/响应状态码(200)/响应状态字符串(ok)

        头:Content-type:text/hmcl;charset=utf-8 Content-length:2048

        空行

        响应体

仅响应行和响应头

需要注意的是响应报文中的响应体一般都是一个html文件<html>...<html/>

AJAX使用到的一些工具(这些是我学习的时候用的 不一定要一样)

VSCODE的下载

 VSCODE直接下载 Visual Studio Code - Code Editing. Redefined

EXPRESS的下载(包括node.js)

安装node.js 下载 | Node.js 中文网 选择合适自己计算机的安装包下载

建议选择安装包 简单快捷

 接下来安装express

  1. 首先以管理员启动VSCODE
  2. 右键一个项目(最外层的文件夹),选择在集成终端打开
  3. 输入命令npm init --yes (此时会出现package-lock.json和package.json文件)
  4. 执行命令npm i express

 此时就安装成功了

NODEMON(一个可以在改变服务端代码之后重新启动服务的工具)

直接在终端上输入回车即可

npm install -g nodemon

 准备工作已经完成 接下来就是具体的AJAX操作方法

AJAX简单使用方法

客户端

        客户端使用AJAX发送请求的四大步骤

        GET方法实例

  1. {
  2. // 进行ajax操作
  3. // 1 创建对象
  4. const xhr = new XMLHttpRequest();
  5. // 2 初始化 设置请求方法和url
  6. // xhr.open('GET', 'http://127.0.0.1:8000/server');
  7. // 可以对url进行追加参数
  8. // xhr.open('GET', 'http://127.0.0.1:8000/server?a=100&b=200&c=300');
  9. // 3 发送
  10. xhr.send();
  11. // 4 绑定事件 处理服务端返回的结果
  12. // readystate是xhr的属性,有0(初始化)、1(open)、2(send)
  13. // 3(服务端返回部分结果)、4(服务端返回所有结果)五个值
  14. xhr.onreadystatechange = function () {
  15. // 此函数要触发4次,每次改变状态的时候会触发 因此要判断状态
  16. // 若返回所有的结果
  17. if (xhr.readyState == 4) {
  18. // 响应状态码为ok时 处理数据
  19. if (xhr.status >= 200 && xhr.status <= 300) {
  20. // 响应行 响应头
  21. // 控制台中显示请求报文的相关信息和响应报文
  22. console.log(xhr.status);
  23. console.log(xhr.statusText);
  24. console.log(xhr.getAllResponseHeaders());
  25. console.log(xhr.response);
  26. // 点击按钮,从服务端获取数据就大功告成了!
  27. }
  28. }
  29. }
  30. }

        POST方法实例

  1. {
  2. const xhr = new XMLHttpRequest();
  3. xhr.open('POST', 'http://127.0.0.1:8000/server');
  4. // --------------------------
  5. // 设置请求头 接收键值对
  6. // xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
  7. // Content - type 设置请求体的类型
  8. // 自定义头信息可以设置 但浏览器会报错
  9. // xhr.setRequestHeader('name', 'Jess');
  10. // --------------------------------- 以上东西有风险
  11. // POST可以设置请求体,包含请求参数
  12. xhr.send('a=100&b=200&c=300');
  13. // xhr.send('a:100&b:200&c:300');
  14. // xhr.send('1234567890');
  15. xhr.onreadystatechange = () => {
  16. if (xhr.readyState == 4) {
  17. if (xhr.status >= 200 && xhr.status <= 300) {
  18. result.innerHTML = xhr.response;
  19. }
  20. }
  21. }
  22. }

服务端

        服务端对请求做出响应

  1. const { request } = require('express');
  2. const { response } = require('express');
  3. const { application } = require('express');
  4. const { json } = require('express/lib/response');
  5. // ----------------------------------
  6. // 1 引入express(有了这句会生成上面的4行代码)
  7. const express = require('express');
  8. // ----------------------------------
  9. // ----------------------------------
  10. // 2 创建应用对象
  11. const app = express();
  12. // ----------------------------------
  13. // ----------------------------------
  14. // 3 创建路由规则
  15. // 创建路由规则 请求报文和响应报文 get请求和post请求的路由规则不同
  16. // ----------------------------------
  17. // server作为url 响应在客户端对应的url
  18. app.get('/server',(request,response)=>{
  19. // 设置响应头,允许跨域
  20. response.setHeader('Access-Control-Allow-Origin','*');
  21. // 设置响应
  22. // 此处尽情发挥
  23. response.send('Hello-RESPONSE-AJAX');
  24. })
  25. // post这里实际上不能运行,因为在客户端已经自定义了请求头
  26. app.post('/server',(request,response)=>{
  27. // 设置响应头,允许跨域
  28. response.setHeader('Access-Control-Allow-Origin','*');
  29. // 设置允许接收所有类型的请求头 但此时浏览器还有一个OPTION类型的请求进行校验 将post改为all即可
  30. response.setHeader('Access-Control-Allow-Header','*')
  31. // 设置响应体
  32. response.send('Hello AJAXPOST');
  33. })
  34. // 应该用all方法来处理POST中设置自定义的请求头
  35. app.all('/server',(request,response)=>{
  36. // 设置响应头,允许跨域
  37. response.setHeader('Access-Control-Allow-Origin','*');
  38. // 设置允许接收所有类型的请求头 但此时浏览器还有一个OPTION类型的请求进行校验 将post改为all即可
  39. response.setHeader('Access-Control-Allow-Headers','*');
  40. // 设置响应体
  41. response.send('HelloAJAXPOSTDeam');
  42. })
  43. // 8000是一个端口,开启服务的时候占的端口号(可自定义)
  44. app.listen(8000,()=>{
  45. console.log("服务已启动,端口8000正在监听......");
  46. })

AJAX的超时与网络异常      

  • onerror()当网络异常时执行的回调函数
  • abort()取消发送请求
  • ontimeout()超过timeout规定的时间则执行函数

        

  1. 重复发送请求
  2. 设置一个标志,记录是否已经发送请求,如果是,则取消当前请求并重新发送请求
  3. // 解决重复发送请求问题 降低服务器压力
  4. {
  5. let isSending = false;
  6. if (isSending) {
  7. xhr.abort();
  8. }
  9. const xhr = new XMLHttpRequest();
  10. isSending = true;
  11. // 超时设置
  12. xhr.timeout = 2000;
  13. // 超时回调
  14. xhr.ontimeout = () => {
  15. alert('发送超时!请稍后重试')
  16. }
  17. // 网络异常
  18. xhr.onerror = () => {
  19. alert('网络异常');
  20. }
  21. xhr.open('GET', 'http://127.0.0.1:8000/server');
  22. xhr.send();
  23. xhr.onreadystatechange = () => {
  24. if (xhr.readyState == 4) {
  25. isSending = false;
  26. }
  27. }
  28. });

 

利用axios函数和fetch函数发送异步请求

axios函数

        AXIOS是Vue 和 React 推荐的AJAX API 官方文档 : axios中文网|axios API 中文文档 | axios

        用script标签引入即可使用

axios函数使用方法

<script crossorigin="anonymous" src="https://cdn.bootcdn.net/ajax/libs/axios/0.27.2/axios.js"></script>
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7. <title>Document</title>
  8. <!-- <script src="https://unpkg.com/axios/dist/axios.min.js"></script> -->
  9. <script crossorigin="anonymous" src="https://cdn.bootcdn.net/ajax/libs/axios/0.27.2/axios.js"></script>
  10. </head>
  11. <body>
  12. <button>GET</button>
  13. <button>POST</button>
  14. <button>AXIOS</button>
  15. <script>
  16. const btn = document.querySelectorAll('button');
  17. // get方法 url用'' 导入
  18. // 创建axios实例
  19. btn[0].onclick = function () {
  20. axios.get('http://127.0.0.1:8000/axios-server', {
  21. params: {
  22. ID: 12345
  23. }
  24. })
  25. }
  26. // post方法第一个{}中必须是请求体,请求参数和请求头以对象的形式写入
  27. btn[1].onclick = function () {
  28. axios.post('http://127.0.0.1:8000/axios-server', {
  29. username: 'Jess'
  30. }, {
  31. params: {
  32. id: 123123
  33. },
  34. headers: {
  35. name: 'Jess'
  36. }
  37. });
  38. }
  39. // 推荐AXIOS发送请求
  40. // 将所有的参数都写在一起 方便快捷
  41. // method和url必须写出并在首位
  42. btn[2].onclick = function () {
  43. axios({
  44. method: 'POST',
  45. url: 'http://127.0.0.1:8000/axios-server',
  46. params: {
  47. id: 10,
  48. level: 30
  49. },
  50. headers: {
  51. a: 100,
  52. b: 200
  53. },
  54. data: {
  55. username: 'admin',
  56. pwd: 'admin'
  57. }
  58. }).then(response => {
  59. console.log(response.status);
  60. console.log(response.statusText);
  61. console.log(response.headers);
  62. // 响应体
  63. console.log(response.data);
  64. })
  65. }
  66. </script>
  67. </body>
  68. </html>
  69. //服务端
  70. //--------------------------
  71. // 响应axios
  72. app.all('/axios-server',(request,response)=>{
  73. // 设置响应头,允许跨域
  74. response.setHeader('Access-Control-Allow-Origin','*');
  75. // 设置允许接收所有类型的请求头 但此时浏览器还有一个OPTION类型的请求进行校验 以all即可
  76. response.setHeader('Access-Control-Allow-Headers','*');
  77. // 设置响应体
  78. response.send('HelloAJAXAXIOS');
  79. })

 fetch函数

        fetch()也可以发送AJAX请求

        这里提一下,服务器发送JSON对象

  1. fetch('http://127.0.0.1:8000/fetch-server', {
  2. // 请求方法
  3. method: 'POST',
  4. // 请求头
  5. headers: {
  6. name: 'Jess'
  7. },
  8. // 请求体
  9. body: 'username=admin&password=admin'
  10. }).then(response => {
  11. // text是一个对response.content内容进行解码的一个函数
  12. // console.log(response);
  13. return response.text();
  14. // 如果返回的是一个JSON对象
  15. // return response.json();
  16. }).then(response => {
  17. console.log(response);
  18. })
  19. //服务端
  20. app.all('/fetch-server',(request,response)=>{
  21. // 设置响应头,允许跨域
  22. response.setHeader('Access-Control-Allow-Origin','*');
  23. // 设置允许接收所有类型的请求头 但此时浏览器还有一个OPTION类型的请求进行校验 以all即可
  24. response.setHeader('Access-Control-Allow-Headers','*');
  25. // 设置响应体
  26. response.send('HelloAJAXFETCH');
  27. })

解决跨域问题的策略

        同源策略(Sameoriginpolicy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响

        同源需要做到 : 协议、域名、端口都要相同

 

 解决方法1

        在路由规则中设置响应头:

  1. 设置响应头,允许跨域
  2. response.setHeader('Access-Control-Allow-Origin','*');

 

解决方法2

        JSONP 即通过script标签引用路由规则的方法

        此方法最常用 但也有许多坑,需要注意服务器返回的东西需要让Javascript解析因此不能乱传数据.

  1. <body>
  2. 用户名:<input type="text" id="username">
  3. <p></p>
  4. <script>
  5. const input = document.getElementById('username');
  6. function handle(data) {
  7. const p = document.querySelector('p');
  8. p.innerHTML = data.msg;
  9. }
  10. input.onblur = function () {
  11. let uname = this.value;
  12. // 发送请求
  13. const script = document.createElement('script');
  14. script.src = 'http://127.0.0.1:8000/check-server';
  15. // 在body中追加script节点
  16. document.body.append(script);
  17. }
  18. </script>
  19. </body>
  20. app.all('/JSONP-server',(request,response)=>{
  21. // jsonp就是利用script标签不受同源策略限制的这一点,通过get的方式执行后端返回的js脚本
  22. // 重点在是只能用GET方式执行
  23. const data ={
  24. name:'Jess'
  25. }
  26. let str = JSON.stringify(data);
  27. // 使用end函数
  28. // ${ }是es6新增的字符串方法,可以配合``单反引号完成字符串拼接的功能
  29. // 用法:(1). 定义需要拼接的字符串
  30. //2). 将字符串用${ }包起来,写到需要拼接的地方
  31. // 返回结果
  32. response.end(`handle(${str})`);
  33. // 返回结果不想其他服务一样,如果用JSONP服务的话单纯返回数据 浏览器无法解析
  34. // 因为是引用 所有返回的数据需要Javascript解析
  35. // 因此需要返回JS语句或者函数等可被解析的代码
  36. })

结语:

        写了这么多,花了2、3个小时整理,期间遇到不太理解的又重新学习一番 

        学时2天 将学过知识总结凝练 以供以后思考反思

        希望走过路过的大佬们 指出问题 不胜感激!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/煮酒与君饮/article/detail/821676
推荐阅读
相关标签
  

闽ICP备14008679号