IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> AJAX教程 -> 正文阅读

[JavaScript知识库]AJAX教程

1.Ajax概述

1.1 AJAX 简介

? AJAX 全称为Asynchronous JavaScript And XML,就是异步的JS 和XML通过AJAX 可以在浏览器中向服务器发送异步请求,最大的优势:无刷新获取数据

? AJAX 不是新的编程语言,而是一种将现有的标准组合在一起使用的新方式

1.2 XML 简介

? XML 可扩展标记语言。
? XML 被设计用来传输和存储数据。
? XML 和HTML 类似,不同的是HTML 中都是预定义标签,而XML 中没有预定义标签,
全都是自定义标签,用来表示一些数据。

比如说我有一个学生数据:
name = “孙悟空” ; age = 18 ; gender = “男” ;
用XML 表示:

<student>
	<name>孙悟空</name>
	<age>18</age>
	<gender></gender>
</student>

现在已经被JSON 取代了。

{"name":"孙悟空","age":18,"gender":"男"}

1.3 AJAX 的特点

1.3.1 AJAX 的优点

? 1.可以无需刷新页面而与服务器端进行通信

? 2.允许你根据用户事件来更新部分页面内容

1.3.2 AJAX 的缺点

  1. 没有浏览历史,不能回退
  2. 存在跨域问题(同源)
  3. SEO 不友好

2. HTTP相关问题

2.1 MDN 文档

MDN参考网站

2.2 HTTP 请求交互的基本过程

img

  1. 前后应用从浏览器端向服务器发送HTTP 请求(请求报文)
  2. 后台服务器接收到请求后, 调度服务器应用处理请求, 向浏览器端返回HTTP响应(响应报文)
  3. 浏览器端接收到响应, 解析显示响应体/调用监视回调

2.3 HTTP 请求报文

1.请求行

? method url
? GET /product_detail?id=2
? POST /login

2.多个请求头

? Host: www.baidu.com
? Cookie: BAIDUID=AD3B0FA706E; BIDUPSID=AD3B0FA706;
? Content-Type: application/x-www-form-urlencoded 或者application/json

3.请求体

? username=tom&pwd=123
? {"username": "tom", "pwd": 123}

2.4 HTTP 响应报文

1.响应状态行: status statusText
2.多个响应头
Content-Type: text/html;charset=utf-8
Set-Cookie: BD_CK_SAM=1;path=/
3.响应体
html 文本/json 文本/js/css/图片...

2.5 post 请求体参数格式

  1. Content-Type: application/x-www-form-urlencoded;charset=utf-8
    用于键值对参数,参数的键值用=连接, 参数之间用&连接
    例如: name=%E5%B0%8F%E6%98%8E&age=12
  2. Content-Type: application/json;charset=utf-8
    用于 json 字符串参数
    例如: {"name": "%E5%B0%8F%E6%98%8E", "age": 12}
  3. Content-Type: multipart/form-data
    用于文件上传请求

2.6 常见的响应状态码

200 OK 请求成功。一般用于GET 与POST 请求
201 Created 已创建。成功请求并创建了新的资源
401 Unauthorized 未授权/请求要求用户的身份认证
404 Not Found 服务器无法根据客户端的请求找到资源
500 Internal Server Error 服务器内部错误,无法完成请求

2.7 不同类型的请求及其作用

  1. GET: 从服务器端读取数据(查)
  2. POST: 向服务器端添加新数据 (增)
  3. PUT: 更新服务器端已经数据 (改)
  4. DELETE: 删除服务器端数据 (删)

2.8 API 的分类

1.REST API: restful (Representational State Transfer (资源)表现层状态转化)

? (1) 发送请求进行CRUD 哪个操作由请求方式来决定
? (2) 同一个请求路径可以进行多个操作
? (3) 请求方式会用到GET/POST/PUT/DELETE

2.非REST API: restless

? (1) 请求方式不决定请求的CRUD 操作
? (2) 一个请求路径只对应一个操作
? (3) 一般只有GET/POST

2.9 区别 一般http请求 与 ajax请求

  1. ajax请求 是一种特别的 http请求
  2. 对服务器端来说, 没有任何区别, 区别在浏览器端
  3. 浏览器端发请求: 只有XHRfetch 发出的才是ajax 请求, 其它所有的都是非ajax 请求
  4. 浏览器端接收到响应
    (1) 一般请求: 浏览器一般会直接显示响应体数据, 也就是我们常说的刷新/跳转页面
    (2) ajax请求: 浏览器不会对界面进行任何更新操作, 只是调用监视的回调函数传入响应相关数据

3. 原生AJAX 的基本使用 XHR

3.0 准备工作

3.0.1 安装node.js

nodejs下载网址

3.0.2 安装express(服务端框架)

express官网

img

  1. 初始化环境
npm init --yes

? 2.下载express包

npm install express --save

? 3.编写js代码

// 1. 引入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 端口监听中...");
 })

? 4.运行js程序

node .\express的基本使用.js

在这里插入图片描述

? 5.打开网页显示页面

在这里插入图片描述

6.调试程序可以查看请求和响应

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.0.3 安装nodemon自动重启工具

文件内容有修改自动重新启动服务

nodemon下载网址

img

安装

npm install -g nodemon

启动服务

nodemon server.js

注意:启动时可能会报以下错误

nodemon : 无法加载文件 C:\Users\cell\AppData\Roaming\npm\nodemon.ps1,因为在此系统上禁止运行脚本。有关详细信息,请参阅 https:/go.microsoft.com/fwlink/?LinkID=135170 中的 about_Execution_Policies。 

在这里插入图片描述

解决方案:

(1) 管理员身份运行PowerShell

(2)输入下面命令并回车

set-ExecutionPolicy RemoteSigned

(3)选择Y

在这里插入图片描述

(4)重新尝试

在这里插入图片描述

3.1 理解

  1. 使用XMLHttpRequest (XHR)对象可以与服务器交互, 也就是发送ajax 请求
  2. 前端可以获取到数据,而无需让整个的页面刷新。
  3. 这使得Web 页面可以只更新页面的局部,而不影响用户的操作。

XMLHttpRequest解释
XMLHttpRequest,AJAX 的所有操作都是通过该对象进行的

3.2 核心对象使用步骤

3.2.1 创建XMLHttpRequest 对象

var xhr = new XMLHttpRequest();

3.2.2 设置请求信息(请求方法和url)

// 请求方式
xhr.open(method, url);
//可以设置请求头,一般不设置
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');

3.2.3 发送请求

xhr.send(body) //get请求不传 body 参数,只有post请求使用

3.2.4 接收响应(事件绑定,处理服务端返回的结果)

      //4.事件绑定 处理服务端返回的结果
      //onreadystatechange单词意思拆分:
        //on 有when的意思,可以理解为当....时候
        //readystate是xhr对象中的属性,表示状态 有五个值,分别为0 1 2 3 4
            //0状态表示未初始化
            //1表示open方法已经调用完毕
            //2表示send方法已经调用完毕
            //3表示服务端返回了部分的结果
            //4表示服务端返回了全部的结果
        //change 表示改变
	xhr.onreadystatechange = function (){
	if(xhr.readyState == 4 && xhr.status == 200){
		var text = xhr.responseText;
		console.log(text);
	}
}

3.2.5 整体页面代码

<!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>AJAX GET 请求</title>
  <style>
    #result{
      width: 200px;
      height: 100px;
      border: solid 1px #90b;
    }
  </style>
</head>
<body>
  <button>点击发送请求</button>
  <div id="result">
    
  </div>
  <script>
    //获取button元素
    const btn=document.getElementsByTagName('button')[0];
    const result=document.getElementById("result");
    //绑定事件
    btn.onclick=function(){
      //1.创建对象
      const xhr=new XMLHttpRequest();
      //2.初始化 设置请求方法和url
      xhr.open('GET','http://localhost:8000/server?a=100&b=200&c=300')
      //3.发送
      xhr.send();
      //4.事件绑定 处理服务端返回的结果
      //onreadystatechange单词意思拆分:
        //on 有when的意思,可以理解为当....时候
        //readystate是xhr对象中的属性,表示状态 有五个值,分别为0 1 2 3 4
            //0状态表示未初始化
            //1表示open方法已经调用完毕
            //2表示send方法已经调用完毕
            //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);//响应体

            //设置result的文本
            result.innerHTML=xhr.response;
          }
        }
      }
    }
  </script>
</body>
</html>

3.3 使用案例

3.3.1 GET 请求

点击返回响应信息

img

创建两个文件,浏览器端使用的html文件和服务器端使用的js文件
在这里插入图片描述
服务器端 server.js

//1.引入express
const express = require('express')

//2.创建应用对象
const app = express()

//3.创建路由规则
//request是对请求报文的封装
//response是对相应报文的封装
app.get('/serve', (request, response) => {
  //设置响应头 设置允许跨域
  response.setHeader('Access-Control-Allow-Origin', '*')
  //设置响应体
  response.send('HELLO AJAX')
})

//4.监听端口启动服务
app.listen(8000, () => {
  console.log('服务已经启动,8000端口监听中.....')
})

启动服务

node .\server.js 

在这里插入图片描述

前端页面HTML

<!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>Ajax GET 请求</title>
  <style>
    #result {
      width: 200px;
      height: 100px;
      border: solid 1px #90b;
    }
  </style>
</head>
<body>
  <button>点击发送请求</button>
  <div id="result"></div>
  <script>
    //获取button元素
    const btn = document.getElementsByTagName('button')[0];
    const result = document.getElementById('result');
    //绑定事件
    btn.onclick = function(){
      // 1. 创建对象 
      const xhr = new XMLHttpRequest();
      // 2. 初始化 设置请求方法和url
      xhr.open('GET', 'http://localhost:8000/server')
      // 3. 发送
      xhr.send();
      // 4. 事件绑定 处理服务端返回的结果
      xhr.onreadystatechange = function(){
        // readyState 是 xhr 对象中的属性, 表示状态 0 1 2 3 4
        //判断 (服务端返回了所有的结果)
        if(xhr.readyState === 4){
          //判断响应状态码 200  404  403 401 500
          if(xhr.status >= 200 && xhr.status < 300){
            // 处理结果 行 头 空行 体
            // 响应
            console.log('状态码', xhr.status); // 状态码
            console.log('状态字符串', xhr.statusText); // 状态字符串
            console.log('所有响应头', xhr.getAllResponseHeaders()); // 所有响应头
            console.log('响应体', xhr.response); // 响应体
            
            //设置 result 的文本
            result.innerHTML=xhr.response;
          }else{
          }
        }
      } 
    }
  </script>
</body>
</html>

img

# GET 请求设置请求参数

设置url参数

xhr.open('GET', 'http://localhost:8000/server?a=100&b=200&c=300');

在这里插入图片描述
在这里插入图片描述

3.3.2 POST请求

鼠标放到div中,发post请求,将响应体放在div中呈现

server.js添加post

app.post('/server', (request, response) => {
  // 设置响应头, 设置允许跨域
  response.setHeader('Access-Control-Allow-Origin', '*');
  // 设置响应体
  response.send("Hello Ajax POST");
});

POST.html

<!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>AJAX POST 请求</title>
  <style>
    #result{
      width: 200px;
      height: 100px;
      border: solid 1px #903;
    }
  </style>
</head>
<body>
  <div id="result"></div>
  <script>
    //获取元素对象
    const result=document.getElementById("result")
    //绑定事件
    result.addEventListener("mouseover",function(){
      // console.log("test");
      //1.创建对象
      const xhr=new XMLHttpRequest();
      //2.初始化 设置请求类型和URL
      xhr.open('POST','http://localhost:8000/server')
      //3.发送
      xhr.send();
      //4.事件绑定
      xhr.onreadystatechange=function(){
        //判断状态
        if(xhr.readyState===4){
          if(xhr.status>=200&&xhr.status<300){
            //处理服务端返回的结果
            result.innerHTML=xhr.response
          }
        }
      }
    })
  </script>
</body>
</html>

img

打开浏览器调试工具,查看请求头和响应头详细信息

在这里插入图片描述在这里插入图片描述
在这里插入图片描述

#post请求设置请求参数

在POST.html的 xhr.send();的内部设置参数

//3.发送(两种参数写法,任选一种,其中第一种格式是常用写法)
xhr.send('a=100&b=200&c=300');//第一种
xhr.send('a:100&b:200&c:300');//第二种

在这里插入图片描述
在这里插入图片描述

// 设置请求体内容的类型(传递两个参数,第一个参数为请求头的名字,第二个为请求头的值)
//Content-Type用于设置请求体内容的类型
//application/x-www-from-urlencoded用于设置参数查询类型,固定写法
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
// 自定义头信息
xhr.setRequestHeader('name', 'zxllove');

在这里插入图片描述

自定义请求头:

在这里插入图片描述
在这里插入图片描述

注意:自定义请求头会报错,原因是自定义的请求头不是预定义的请求头,浏览器会启动安全机制

解决办法

在server.js中设置响应头允许自定义请求头 post改成all,并将response.setHeader('Access-Control-Allow-Headers', '*')加入到代码中,然后关闭server.js,在终端中重新启动(在实际工作当中,这个事情由后端人员处理)

完整版代码:

//all表示可以接收任意类型的请求
app.all('/server', (request, response) => {
  //设置响应头 设置允许跨域
  response.setHeader('Access-Control-Allow-Origin', '*')
  //响应头
  response.setHeader('Access-Control-Allow-Headers', '*')
  //设置响应体
  response.send('HELLO AJAX POST')
})

3.4 json数据请求

server.js

//all表示可以接收任意类型的请求
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)
})

json.html

<!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>JSON响应</title>
  <style>
    #result{
      width: 200px;
      height: 100px;
      border: solid 1px #89b;
    }
  </style>
</head>
<body>
  <div id="result"></div>
  <script>
    //获取元素对象
    const result=document.getElementById("result")
    //绑定键盘按下事件
    window.onkeydown=function(){
      // console.log('test');
      //发送请求
      const xhr=new XMLHttpRequest();
      //*2*.(自动转换)设置响应体数据的类型
      xhr.responseType='json'
      //初始化
      xhr.open('GET','http://localhost:8000/json-server');
      //发送
      xhr.send();
      //事件绑定
      xhr.onreadystatechange=function(){
        //判断状态
        if(xhr.readyState===4){
          if(xhr.status >=200&&xhr.status<300){
            //设置result的文本
            console.log(xhr.response);
            //1.手动对数据转化 (字符串再转换成json)
            // let data=JSON.parse(xhr.response)//转换成json
            // console.log(data);
            // result.innerHTML = data.name;
            //*2*.自动转换
            result.innerHTML = xhr.response.name;//已经自动变成json
          }
        }
      }
    }
  </script>
</body>
</html>

在这里插入图片描述

3.5 解决 IE 缓存问题

问题:在一些浏览器中(IE),由于缓存机制的存在,ajax 只会发送的第一次请求,剩余多次请求不会在发送给浏览器而是直接加载缓存中的数据。

测试代码

IE缓存问题.html

<!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>IE缓存问题</title>
  <style>
    #result{
    width: 200px;
    height: 100px;
    border: solid 1px #89b;
  }
  </style>
</head>
<body>
  <button>点击发送请求</button>
  <div id="result"></div>
  <script>
    const btn=document.getElementsByTagName('button')[0]
    const result=document.querySelector('#result')
    btn.addEventListener('click',function(){
      console.log('Test');
      const xhr=new XMLHttpRequest();
      xhr.open('GET','http://localhost:8000/ie')
      xhr.send()
      xhr.onreadystatechange=function(){
        if(xhr.readyState===4){
          if(xhr.status >=200&&xhr.status<300){
            result.innerHTML=xhr.response
          }
        }
      }
    })
  </script>
</body>
</html>

server.js

//针对IE缓存
app.get('/ie', (request, response) => {
  //设置响应头 设置允许跨域
  response.setHeader('Access-Control-Allow-Origin', '*')
  //设置响应体
  response.send('HELLO IE')
})

1.在ie浏览器中打开页面,点击button按钮发送请求,发现页面正常显示HELLO IE

2.打开server.js文件将response.send('HELLO IE')修改 response.send('HELLO IE--2'),并保存,重新在页面中点击button按钮,发现页面依然显示HELLO IE

解决方式:浏览器的缓存是根据url 地址来记录的,所以我们只需要修改url 地址即可避免缓存问题

xhr.open('GET','http://localhost:8000/ie?t='+Date.now())

3.6 请求超时与网络异常

超时与网络异常.html

<!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>
  <style>
    #result{
      width: 200px;
      height: 100px;
      border: solid 1px #90b;
    }
  </style>
</head>
<body>
  <button>点击发送请求</button>
  <div id="result"></div>
  <script>
    const btn=document.getElementsByTagName('button')[0]
    const result=document.querySelector('#result')
    btn.addEventListener('click',function(){
      console.log('Test');
      const xhr=new XMLHttpRequest();

      //超时设置2秒等待时间,若2秒还未得到服务端的响应则请求就会取消
      xhr.timeout=2000
      //超时回调
      xhr.ontimeout=function(){
        alert('网络超时,请稍后重试!!!')
      }
      // 网络异常回调
      xhr.onerror = function(){
	      alert('网络异常,请稍后重试')
      }
      xhr.open('GET','http://localhost:8000/delay')
      xhr.send()
      xhr.onreadystatechange=function(){
        if(xhr.readyState===4){
          if(xhr.status >=200&&xhr.status<300){
            result.innerHTML=xhr.response
          }
        }
      }
    })
  </script>
</body>
</html>

server.js

//延时响应
app.get('/delay', (request, response) => {
  //设置响应头 设置允许跨域
  response.setHeader('Access-Control-Allow-Origin', '*')
  //延时设置,响应时间为3秒钟
  setTimeout(() => {
    //设置响应体
    response.send('延时响应')
  }, 3000)
})

效果截图:

在这里插入图片描述

在这里插入图片描述

3.7 取消请求

取消请求.html

<!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>取消请求</title>
</head>
<body>
  <button>点击发送</button>
  <button>点击取消</button>
  <script>
    //获取元素对象
    const btns=document.querySelectorAll('button');
    let xhr=null
    btns[0].onclick=function(){
      xhr=new XMLHttpRequest()
      xhr.open('GET','http://localhost:8000/delay')
      xhr.send()
    }
    //调用abort方法取消请求
    btns[1].onclick=function(){
      xhr.abort()
    }
  </script>
</body>
</html>

server.js

//延时响应
app.get('/delay', (request, response) => {
  //设置响应头 设置允许跨域
  response.setHeader('Access-Control-Allow-Origin', '*')
  //延时设置,响应时间为3秒钟
  setTimeout(() => {
    //设置响应体
    response.send('延时响应')
  }, 3000)
})

效果截图:

在这里插入图片描述

3.8请求重复发送问题

问题:当用户重复点击发送的时候,就会有很多个相同的请求发送,这样会给服务器带来很大的压力,处理请求的效率也会大大降低。

解决办法:当用户重复点击发送时,设置一个标识变量,判断用户上一个请求是否还在发送中,如果在发送中,则会取消该请求,重新创建一个新的请求发送。

请求重复发送问题.html

<!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>重复请求问题</title>
</head>
<body>
  <button>点击发送</button>
  <script>
    //获取元素对象
    const btns=document.querySelectorAll('button');
    let xhr=null
    //表示变量
    let isSending=false;//是否正在发送AJAX请求(false表示没有在发送,true表示正在发送)
    btns[0].onclick=function(){
      //判断标识变量
      if(isSending)xhr.abort();//如果正在发送,则取消该请求,创建一个新的请求
      xhr=new XMLHttpRequest()
      //修改 标识变量的值
      isSending=true
      xhr.open('GET','http://localhost:8000/delay')
      xhr.send()
      xhr.onreadystatechange=function(){
        if(xhr.readyState===4){
          //修改标识变量
          isSending=false
        }
      }
    }
  </script>
</body>
</html>

server.js

//延时响应
app.get('/delay', (request, response) => {
  //设置响应头 设置允许跨域
  response.setHeader('Access-Control-Allow-Origin', '*')
  //延时设置,响应时间为3秒钟
  setTimeout(() => {
    //设置响应体
    response.send('延时响应')
  }, 3000)
})

效果截图:

在这里插入图片描述

3.9 AJAX 请求状态

xhr.readyState 可以用来查看请求当前的状态

XMLHttpRequest.readyState解释
在这里插入图片描述

  • 0: 表示XMLHttpRequest 实例已经生成,但是open()方法还没有被调用
  • 1: 表示send()方法还没有被调用,仍然可以使用setRequestHeader(),设定HTTP请求的头信息
  • 2: 表示send()方法已经执行,并且头信息和状态码已经收到
  • 3: 表示正在接收服务器传来的body 部分的数据
  • 4: 表示服务器数据已经完全接收,或者本次接收已经失败了

3.10 API总结

XMLHttpRequest():创建 XHR 对象的构造函数
status:响应状态码值,如 200、404
statusText:响应状态文本,如 ’ok‘、‘not found’
readyState:标识请求状态的只读属性 0-1-2-3-4
onreadystatechange:绑定 readyState 改变的监听
responseType:指定响应数据类型,如果是 ‘json’,得到响应后自动解析响应
response:响应体数据,类型取决于 responseType 的指定
timeout:指定请求超时时间,默认为 0 代表没有限制
ontimeout:绑定超时的监听
onerror:绑定请求网络错误的监听
open():初始化一个请求,参数为:(method, url[, async])
send(data):发送请求
abort():中断请求 (发出到返回之间)
getResponseHeader(name):获取指定名称的响应头值
getAllResponseHeaders():获取所有响应头组成的字符串
setRequestHeader(name, value):设置请求头

4. jQuery中的AJAX

4.1 get 请求

$.get(url, [data], [callback], [type])
  • url:请求的URL 地址
  • data:请求携带的参数
  • callback:载入成功时回调函数
  • type:设置返回内容格式,xml, html, script, json, text, _default
$.get('http://localhost:8000/jquery-server',{a:100,b:200},function(data){console.log(data)},'json')

4.2 post 请求

$.post(url, [data], [callback], [type])
  • url:请求的URL 地址
  • data:请求携带的参数
  • callback:载入成功时回调函数
  • type:设置返回内容格式,xml, html, script, json, text, _default
$.post('http://localhost:8000/jquery-server',{a:100,b:200},function(data){console.log(data)})

在这里插入图片描述

4.3 通用方法

$.ajax({
    // url
    url: 'http://localhost:8000/jquery-server',
    // 参数
    data: {a:100, b:200},
    // 请求类型
    type: 'GET',
    // 响应体结果
    dataType: 'json',
    // 成功的回调
    success: function(data){console.log(data);},
    // 超时时间
    timeout: 4000,
    // 失败的回调
    error: function(){console.log('出错啦~');},
    // 自定义头信息
    headers: {
        c: 300,
        d: 400
    }	
})

更多参数设定可以参考菜鸟教程jQuery ajax() 方法 | 菜鸟教程 (runoob.com)

client.html

<!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>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">jQuery发送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:8000/jquery-server',{a:100,b:200},function(data){
        console.log(data);
      },'json')
    })
    $('button').eq(1).click(function(){
      $.post('http://localhost:8000/jquery-server',{a:100,b:200},function(data){
        console.log(data);
      })
    })
    $('button').eq(2).click(function(){
      $.ajax({
        // url
          url: 'http://localhost:8000/jquery-server',
        // 参数
          data: {a:100, b:200},
        // 请求类型
          type: 'GET',
        // 响应体结果
          dataType: 'json',
        // 成功的回调
          success: function(data){console.log(data);},
        // 超时时间
          timeout: 4000,
        // 失败的回调
          error: function(){console.log('出错啦~');},
        // 自定义头信息
          headers: {
            c: 300,
            d: 400
          }	
      })
    })
  </script>
</body>
</html>

server.js

//jQuery 服务
app.all('/jquery-server', (request, response) => {
  //设置响应头 设置允许跨域
  response.setHeader('Access-Control-Allow-Origin', '*')
  //响应头
  response.setHeader('Access-Control-Allow-Headers', '*')
  //设置响应体
  const data = { name: 'lovely_ll' }
  // setTimeout(() => {
  response.send(JSON.stringify(data))
  // }, 2000)
})

5.Axios中的AJAX

axios的GitHub官网

baseURL设定:在写URL地址时,可以在代码中省去前面的ip地址和端口号,直接写后面的请求地址

axios.defaults.baseURL='http://localhost:8000'

5.1 get请求

axios.get(url,[config]).then(value=>{})
  • url:请求的URL 地址
  • config:请求携带的参数设定
  • value:请求回来的返回结果,对象形式
axios.defaults.baseURL='http://localhost:8000'
//GET请求
axios.get('/axios-server',{
    //url参数
    params:{
        id:100,
        vip:7
    },
   	//请求头信息
    headers:{
        name:'lovely_ll',
        age:21
    }
}).then(value=>{console.log(value)})

5.2 post请求

axios.post(url,[data],[config]).then(value=>{})
  • url:请求的URL 地址

  • data:请求体内容

  • config:请求携带的参数

  • value:请求回来的返回结果,对象形式

//POST请求
axios.post('/axios-server',{username:'admin',password:'123456'},
    {
    //url参数
    params:{
        id:200,
        vip:9
    },
    //请求头信息
    headers:{
        height:180,
        weight:200
    },
}).then(value=>{console.log(value)})

在这里插入图片描述

5.3 通用方法

axios({
    //请求方法
    method:'POST',
    //url
    url:'/axios-server',
    //url参数
    params:{
        vip:10,
        level:30
    },
    //头信息
    headers:{
        a:100,
        b:200
    },
    //请求体参数
    data:{
        username:'admin',
        password:'123456'
    }
}).then(value=>{
    console.log(value)
    //响应状态码
    console.log(value.status)
    //响应状态字符串
    console.log(value.statusText)
    //响应头信息
    console.log(value.headers)
    //响应体
    console.log(value.data)
})

在这里插入图片描述
在这里插入图片描述

axios.html

<!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>axios 发送 AJAX请求</title>
  <script crossorigin="anonymous" src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
</head>
<body>
  <button>GET</button>
  <button>POST</button>
  <button>AJAX</button>
  <script>
    const btns=document.querySelectorAll('button')
    axios.defaults.baseURL='http://localhost:8000'
    btns[0].onclick=function(){
      //GET请求
      axios.get('/axios-server',{
        //url参数
        params:{
          id:100,
          vip:7
        },
        //请求头信息
        headers:{
          name:'lovely_ll',
          age:21
        }
      }).then(value=>{
        console.log(value);
      })
    }

    btns[1].onclick=function(){
      //POST请求
      axios.post('/axios-server',{username:'admin',password:'123456'},
      {
        //url参数
        params:{
          id:200,
          vip:9
        },
        //请求头信息
        headers:{
          height:180,
          weight:200
        },
      }).then(value=>{
        console.log(value);
      })
    }

    btns[2].onclick=function(){
      axios({
        //请求方法
        method:'POST',
        //url
        url:'/axios-server',
        //url参数
        params:{
          vip:10,
          level:30
        },
        //头信息
        headers:{
          a:100,
          b:200
        },
        //请求体参数
        data:{
          username:'admin',
          password:'123456'
        }
      }).then(value=>{
        console.log(value)
        //响应状态码
        console.log(value.status)
        //响应状态字符串
        console.log(value.statusText)
        //响应头信息
        console.log(value.headers)
        //响应体
        console.log(value.data)
      })
    }
  </script>
</body>
</html>

server.js

//axios 服务
app.all('/axios-server', (request, response) => {
  //设置响应头 设置允许跨域
  response.setHeader('Access-Control-Allow-Origin', '*')
  //响应头
  response.setHeader('Access-Control-Allow-Headers', '*')
  //设置响应体
  const data = { name: 'lovely_ll' }
  response.send(JSON.stringify(data))
})

6. fetch中的AJAX

fetch参考网站

fetch(url,[init]).then(promise=>{})
  • url:请求的URL 地址
  • init:一个配置项对象,包括所有对请求的设置,是一个可选的配置项
  • promise:返回值为一个Promise对象

fetch.html

<!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>fetch 发送 AJAX请求</title>
</head>
<body>
  <button>AJAX请求</button>
  <script>
    const btn = document.querySelector('button');
    btn.onclick = function(){
      fetch('http://localhost:8000/fetch-server?vip=10', {
        //请求方法
        method: 'POST',
        //请求头
        headers: {
          name: 'lovely_ll'
        },
        //请求体
        body: 'username=admin&password=admin'
      }).then(response => {
        // console.log(response);

        //获取响应体内容
        // return response.text();//响应体内容为字符串格式
        return response.json();//响应体内容为json格式
      }).then(response => {
        console.log(response);
      })
    }
  </script>
</body>
</html>

server.js

//fetch 服务
app.all('/fetch-server', (request, response) => {
  //设置响应头 设置允许跨域
  response.setHeader('Access-Control-Allow-Origin', '*')
  //响应头
  response.setHeader('Access-Control-Allow-Headers', '*')
  //设置响应体
  const data = { name: 'lovely_ll' }
  response.send(JSON.stringify(data))
})

在这里插入图片描述
在这里插入图片描述

7. 跨域

7.1 同源策略

  • 同源策略(Same-Origin Policy)最早由Netscape 公司提出,是浏览器的一种安全策略
  • 同源: 协议、域名、端口号必须完全相同
  • 跨域: 违背同源策略就是跨域

7.2 如何解决跨域

7.2.1 JSONP

1) JSONP 是什么

JSONP(JSON with Padding),是一个非官方的跨域解决方案,纯粹凭借程序员的聪明才智开发出来,只支持get 请求。

2) JSONP 怎么工作的?

在网页有一些标签天生具有跨域能力,比如:img link iframe script。JSONP 就是利用script 标签的跨域能力来发送请求的。

3) JSONP 原理

前端声明好处理函数,通过script标签向服务服务端发送请求,后端通过调用前端声明好的函数,函数内部的参数为用户数据,以js形式返回。

原理.html

<!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>
  <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 src="http://127.0.0.1:5500/%E4%BB%A3%E7%A0%81/6-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>

server.js

//jsonp 服务
app.all('/jsonp-server', (request, response) => {
  // response.send('console.log("hello jsonp-server")')
  const data = {
    name: 'lovely_ll的学习笔记-2',
  }
  let str = JSON.stringify(data)
  //.end不会加特殊响应头
  response.end(`handle(${str})`)
})

4) JSONP 的使用

1.动态的创建一个script 标签
const script = document.createElement('script');
2.设置script 的src,设置回调函数
script.src = 'http://localhost:8000/check-username';
function handle(data){
    //修改边框颜色
    input.style.border = "solid 1px #f00";
    //修改 p 标签的提交文本
    p.innerHTML = data.msg
}
3.将script 添加到body 中
document.body.appendChild(script);

原生JSONP实践.html

<!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>原生JSONP 实践案例</title>
</head>
<body>
  用户名: <input type="text" id="username" >
  <p></p>
  <script>
    //获取input元素
    const input = document.querySelector('input');
    //获取p元素
    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://localhost:8000/check-username';
      //3. 将 script 插入到文档中
      document.body.appendChild(script);
    }
    
  </script>
</body>
</html>

server.js

//用户名检测是否存在
app.all('/check-username', (request, response) => {
  // response.send('console.log("hello jsonp-server")')
  const data = {
    exist: 1,
    msg: '用户名已经存在',
  }
  let str = JSON.stringify(data)
  //.end不会加特殊响应头
  response.end(`handle(${str})`)
})

在这里插入图片描述
在这里插入图片描述

5) jQuery 中的JSONP

$.getJSON(url,function(data){})
  • url:请求的URL 地址
  • function:回调函数
  • data:响应体返回结果,对象形式
$.getJSON('http://localhost:8000/jquery-jsonp-server?callback=?',function(data){
    console.log(data)
    $('#result').html(`
		名称:${data.name}<br>
		爱好:${data.hobby}
	`)
})

在这里插入图片描述
在这里插入图片描述

jQuery-jsonp.html

<!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>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://localhost:8000/jquery-jsonp-server?callback=?',function(data){
        console.log(data)
        $('#result').html(`
            名称:${data.name}<br>
            爱好:${data.hobby}
        `)
      })
    })
  </script>
</body>
</html>

server.js

//jquery的jsonp服务
app.all('/jquery-jsonp-server', (request, response) => {
  const data = {
    name: '可爱_龙龙',
    hobby: ['唱歌', '跳舞', 'rap', '篮球'],
  }
  //将数据转化为字符串
  let str = JSON.stringify(data)
  //接收callback参数
  let cb = request.query.callback
  //.end不会加特殊响应头
  response.end(`${cb}(${str})`)
})

7.2.2 CORS

CORS参考网站

1) CORS 是什么?

? CORS(Cross-Origin Resource Sharing),跨域资源共享。CORS 是官方的跨域解决方案,它的特点是不需要在客户端做任何特殊的操作,完全在服务器中进行处理,支持get 和post 请求。跨域资源共享标准新增了一组HTTP 首部字段,允许服务器声明哪些源站通过浏览器有权限访问哪些资源

2) CORS 怎么工作的?

? CORS 是通过设置一个响应头来告诉浏览器,该请求允许跨域,浏览器收到该响应以后就会对响应放行。

3) CORS 的使用

主要是服务器端的设置:

router.get("/testAJAX" , function (req , res) {
	//通过res 来设置响应头,来允许跨域请求
	//res.set("Access-Control-Allow-Origin","http://localhost:3000");
	res.set("Access-Control-Allow-Origin","*");
	res.send("testAJAX 返回的响应");
});
  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2021-12-13 12:43:13  更:2021-12-13 12:44:55 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 9:18:32-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码