1 . XMLHttpRequest 的基本用法
XMLHttpRequest 的概念
XMLHttpRequest 是浏览器内置的一个构造函数。
axios 中的 axios.get()
、axios.post()
、axios()
方法,都是基于 XMLHttpRequest 封装的!
作用 : 基于 new 出来的 XMLHttpRequest 实例对象,可以发起 Ajax 的请求。
XMLHttpRequest的使用
主要的 4 个实现步骤:
1. 创建 XMLHttpRequest 实例对象
- 语法 :
const xhr = new XMLHttpRequest()
2. 调用 open() 方法创建请求
- 语法 :
xhr.open('请求方式', '请求路径'...);
3. 调用 send() 发送请求
- 语法 :
xhr.send()
4. 监听 load 事件, 对响应数据做处理
- 语法 :
xhr.addEventListener('load', function() { })
// 创建 xhr 对象
const xhr = new XMLHttpRequest();
// 调用 xhr.open() 函数
xhr.open('GET', '请求路径');
// 调用 xhr.send() 函数
xhr.send();
// 监听 load 事件
xhr.addEventListener('load', function() {
console.log(xhr.response);
});
XMLHttpRequest 的常用方法
open()
方法 : 创建了 HTTP 请求
- 第一个参数是请求方式 (get, post)
- 第二个参数是 url 路径
- 第三个参数表示异步还是同步,布尔值( true表示异步,false表示同步,默认值true )
- 第四第五个参数一般不用写( 用于 HTTP 认证 )
setRequestHeader()
方法 : 用来设置请求头信息, post 请求才会用到 , get 请求不需要 - 第一个参数对应的是请求头字段 ( 例 : ‘Content-type’ )
- 第二个参数是请求头字段所对应的值 ( 例 : ‘application/x-www-form-urlencoded’ )
send()
方法 : 发送请求给服务器 - get 请求不需要填写参数
- post 请求把要提交的参数写里面
XMLHttpRequest 的常用属性
onreadystatechange : 请求状态改变的事件触发器( readyState 发生变化是调用 ),一般用于会回调
readyState : 请求状态, 总共有五种状态
- 0 : 未初始化
- 1 : open 方法调用
- 2 : 服务器应答客户请求
- 3 : 交互中, HTTP 头信息被接收, 响应数据未接收
- 4 : 数据接收完成
responseText : 服务器返回的文本内容
reponsseXML : 服务器返回的XML内容(兼容dom)
status : 服务器返回的状态码
statusText : 服务器返回状态码的文本信息
GET请求携带参数
GET请求参数直接放到路径的最末尾就可以!
// 创建 xhr 对象
const xhr = new XMLHttpRequest();
// 调用 xhr.open() 函数 -- get参数
xhr.open('GET', '请求路径?id=1&name=小掘');
// 调用 xhr.send() 函数
xhr.send();
// 监听 load 事件
xhr.addEventListener('load', function() {
console.log(xhr.response);
});
POST请求携带参数
POST请求参数,分为两种:查询参数(几乎不用)和请求体参数(设置头信息)
// 创建 xhr 对象
const xhr = new XMLHttpRequest();
// 调用 xhr.open() 函数 -- get参数
xhr.open('POST', '请求路径');
// 调用 xhr.send() 函数
// 设置头信息
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send('bookname=三体&author=刘慈欣&publisher=北京人民出版社');
// 监听 load 事件
xhr.addEventListener('load', function() {
console.log(xhr.response);
});
注意 : POST请求查询参数几乎不用,且传递POST请求参数需要设置头信息。
2 . Ajax 接收到的数据类型 及 数据交换格式
数据类型
Sring 字符串类型 : 直接使用
JSON 字符串 : 反序列化后转引用数据类型使用(数组或对象)
二进制数据流 : 使用 Blob
数据交换格式 JSON
数据交换格式 : 服务器端与客户端之间数据传输的格式。
两种数据交换格式 : XML 和 JSON ( 常用 )
JSON(全称:JavaScript Object Notation): 是一种数据交换格式,它本质上是用字符串的方式来表示对象或数组类型的数据。
JSON 格式转 JS 数据 : 调用浏览器内置的 JSON.parse()
方法
JS 数据转 JSON 格式 : 调用浏览器内置的 JSON.stringify()
方法
序列化 : 把 js 数据转换为字符串的过程
反序列化 : 把字符串转换为 js 数据的过程
JSON 格式的数据的规则:
- 属性名必须使用双引号包裹
- 字符串类型的值必须使用双引号包裹
- JSON 中不允许使用单引号表示字符串
- JSON 中不能写注释
- JSON 的最外层必须是对象或数组格式
- 不能使用 undefined 或函数作为 JSON 的值
3 . 同源和跨域
同源和跨域
同源 : 指两个 URL 地址具有相同的协议、主机名、端口号。
同源策略 : (英文全称 Same origin policy)是浏览器提供的一个安全功能。不允许非同源的 URL 之间进行资源的交互
跨域 : 指两个 URL 地址的协议、主机名、端口号三者中有一个或多个不同。
出现跨域的原因 :同源策略, 浏览器的同源策略不允许非同源的 URL 之间进行资源的交互。
跨域常用解决方案
JSONP : 利用 script 标签的 src 属性进行跳转(前后端配合解决,与 Ajax 无关)
CORS : 后端下载插件解决
Proxy( 代理服务器 ) : 正向代理,前端自己解决,利用服务器给服务器请求数据
- 弊端 : 解决跨域只适用于本地开发环境, 项目上线后的生产环境无法生效
Nginx : 反向代理, 后端解决
CORS( 后端技术 )
CORS 是解决跨域数据请求的终极解决方案 ( 全称是 Cross-origin resource sharing )该技术需要浏览器和服务器同时支持,二者缺一不可
- 浏览器要支持 CORS 功能(主流的浏览器全部支持,IE 不能低于 IE10)
- 服务器要开启 CORS 功能(需要后端开发者为接口开启 CORS 功能)
CORS 的两个主要优势 : 支持 GET、POST、DELETE、PUT、PATCH 等这些常见的 Ajax 请求方式和只需要后端开启 CORS 功能即可,前端的代码无须做任何改动
JSONP( 前后端配合 )
JSONP 是实现跨域数据请求的一种技术解决方案。
原理 : 动态创建 script 标签, 利用 script 标签的 src 属性, 不受同源策略的限制, 可以请求第三方服务器的数据内容
弊端 : 只支持 GET 请求,不支持 POST、DELETE 等其它请求。在实际业务中很少被使用
注意 :
JSONP 不是真正的 Ajax 技术,在解决跨域问题时 :
- CORS 方案用到了 XMLHttpRequest 对象,发起的是纯正的 Ajax 请求
- JSONP 方案没有用到 XMLHttpRequest 对象,因此,JSONP 不是真正的 Ajax 技术
4 . 手动封装一个 Ajax
前置知识点补充
参数 config
包含的属性 :
method
: 请求方式url
: 资源路径params
: get参数data
: post参数success
: 响应处理函数
toUpperCase()
方法 : 让所有的字符串中内容变大写
toLowerCase()
方法 : 让所有的字符串中内容变小写
// 封装
function itheima(config) {
// 1.创建
const xhr = new XMLHttpRequest();
// 4.接收
xhr.onload = function () {
// 把接收到的数据转换为 对象类型!
let obj = JSON.parse(xhr.response);
// console.log(obj);
config.success(obj);
}
// 根据请求方法不同,给同步的处理代码
if (config.method.toLowerCase() == 'get') {
// 判断 程序员使用这个函数的时候,有没有传递参数:
// 没有传递参数,传递一个字符串a=1&b=2&c=3, 传递了一个对象;
if (typeof config.params == 'undefined') {
// 2.设置
xhr.open('GET', config.url);
} else if (typeof config.params == 'string') {
// 2.设置
xhr.open('GET', config.url + '?' + config.params);
}
// 3.发送
xhr.send();
} else if (config.method.toLowerCase() == 'post') {
// post参数类型三种: FormData类型,对象类型,字符串类型;
// FormData类型判断: config.data instanceof FormData
// 2.设置
xhr.open("POST", config.url);
// 只考虑字符串类型,不考虑其他类型
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
// 3.发送
xhr.send(config.data);
}
}