跨域传输文件格式

218 阅读6分钟

XMLHttpRequest

XMLHttpRequest 是浏览器内置的一个构造函数

作用:基于 new 出来的 XMLHttpRequest 实例对象,可以发起 Ajax 的请求。

axios 中的 axios.get() 、axios.post()axios() 方法,都是基于 XMLHttpRequest(简称:XHR) 封装出来的!

使用 XMLHttpRequest 发起 GET 请求

主要的 4 个实现步骤:

  1. 创建 xhr 对象
  2. 调用 xhr.open() 函数
  3. 调用 xhr.send() 函数
  4. 监听 load 事件

load 事件xhr.response拿到服务器响应回来的数据。

请求时携带URL参数 或 提交请求体

URL参数,只能拼接在 URL 地址 后面 请求体,放到 send() 里面

提交请求体数据,需指定Content-Type头

当需要提交请求体数据时,需要在 xhr.open() 之后,调用 xhr.setRequestHeader() 函数,指定请求体的编码格式

请求体格式Content-Type是否需要在代码中指定
参数=值&参数=值application/x-www-form-urlencoded
'{ "id": 1, "name": "zs" }'application/json
new FormData()multipart/form-data; xxxxxxxxx随机字符否,浏览器自动设置

使用axios就不用关心这个请求头了,因为axios已经帮我们处理好了加请求头这件事 不过写原生代码,就需要自己指定了

数据交换格式

数据交换格式,就是服务器端与客户端之间数据传输的格式。

两种数据交换格式:

  1. XML(很少用)
  2. JSON(主流)
JSON:

JSON是一种数据交换格式,它本质上是用字符串的方式来表示对象或数组类型的数据

JSON 数据的格式有两种:

  1. 对象格式
  2. 数组格式

使用 JSON 定义 JSON 格式的数据时,要遵守以下的 6 条规则:

  1. 属性名必须使用双引号包裹
  2. 字符串类型的值必须使用双引号包裹
  3. JSON 中不允许使用单引号表示字符串
  4. JSON 中不能写注释
  5. JSON 的最外层必须是对象或数组格式(其他类型也可以,但多数是对象或数组格式)
  6. 不能使用 undefined 或函数作为 JSON 的值

数组格式的 JSON 数据

数组格式的 JSON 数据,最外层使用 [ ] 进行包裹,内部的每一项数据之间使用英文的 , 分隔。其中: 每一项的值类型只能是字符串、数字、布尔值、null、数组、对象这 6 种类型之一。

JSON.parse() //把JSON数据转为js数据
JSON.stringify() //把 JS 数据转换为 JSON 格式的字符串
JSON 文件

后缀名是 .json 的文件叫做 JSON 文件,专门用来存储 JSON 格式的数据。

.json 结尾的文件,一般都是项目的配置文件

封装自己的 Ajax 函数

itheima 函数是自定义的 Ajax 函数,它接收一个配置对象作为参数。配置对象中包含如下 5 个参数选项:

参数选项说明
method请求的类型(GET 或 POST)
url请求的 URL 地址
paramsURL 末尾拼接的查询参数
data请求体数据,有三种格式,分别是(FormData 格式、JSON 格式、普通字符串格式)
success请求成功之后的回调函数

初步定义itheima函数

function itheima(options) {
  const xhr = new XMLHttpRequest() // 1. 创建 xhr 实例对象
  xhr.addEventListener('load', function () {
    const result = JSON.parse(xhr.response// 3. 把响应的 JSON 数据转换为 JS 对象
    options.success(result) // 4. 调用 success 成功的回调,把请求的结果当作参数传递进去
  })
  // 2. 根据用户指定的 method 和 url 发起对应的请求
  xhr.open(options.method, options.url)
  xhr.send()
}
​

处理 params 参数

希望达到的结果:把对象格式的 params 转换为“键值对”格式的查询参数,拼接到 URL 地址的末尾。

itheima({
    method: '请求类型',
    url: '请求地址',
    params: { a: 1, b: 2 },
    success: function (result) {
        console.log(result)
    }
})
//xhr.open(options.method, 请求地址?a=1&b=2)
  1. 把“params 对象”转化为“字符串的数组”
  2. 把字符串的数组,调用 join() 函数进行拼接

Snipaste_2022-05-05_19-56-34.png

处理 params 参数 - 核心代码

if (options.params) { // 1.1 如果条件成立,则证明有查询参数
  const qs = []       // 1.2 用来存储“键值对”的空数组
  for (let k in options.params) {
    // 2. 向 qs 数组中追加“键值对”的字符串
    qs.push(`${k}=${options.params[k]}`)
  }
  if (qs.length > 0) {
    // 3. 如果 qs 数组不为空,则把“查询参数”拼接到 url 地址的末尾
    options.url += `?${qs.join('&')}`
  }
}
​

处理 data 请求体数据

希望达到的结果:根据不同的请求体数据,设置对应的请求头的 Content-Type 类型。 请求体的数据有以下三种类型:

Snipaste_2022-05-05_19-57-57.png

判断是否需要携带请求体数据

// 指定请求的“方式”与“地址”
xhr.open(options.method, options.url)
if (options.method.toUpperCase() !== 'GET' && options.data) {
  // 需要携带请求体数据
  // 1. 判断 options.data 是否为 FormData 格式
  // 2. 判断 options.data 是否为“键值对”字符串
  // 3. 判断 options.data 是否为 json 对象格式
} else {
  // 不需要携带请求体数据
  xhr.send()
}
​

处理 data 请求体数据

对象 instanceof 构造函数用来判断一个对象是否为某个构造函数的实例

// 1. 判断 options.data 是否为 FormData 格式
if (options.data instanceof FormData) {
  xhr.send(options.data)
  return
}
​

typeof 值 === 'string' 判断某个值是否为字符串类型?

// 2. 判断 options.data 是否为“键值对”字符串
if (typeof options.data === 'string') {
  xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
  return xhr.send(options.data)
}
​

typeof 值 === 'object' 判断某个值是否为对象类型?

// 3. 判断 options.data 是否为 json 对象格式
if (typeof options.data === 'object') {
  xhr.setRequestHeader('Content-Type', 'application/json')
  return xhr.send(JSON.stringify(options.data))
}
​

同源策略 & 跨域

同源指的是两个 URL 地址具有相同的协议、主机名、端口号。

URL是否同源原因说明
www.test.com/other.html同源(协议、域名、端口相同)
www.test.com/about.html协议不同(http 与 https)
blog.test.com/movie.html域名不同(www.test.com 与 blog.test.com)
www.test.com:7001/home.html端口不同(默认的 80 端口与 7001 端口)
www.test.com:80/main.html同源(协议、域名、端口相同)

同源策略:

浏览器提供的一个安全功能。 浏览器的同源策略规定:不允许非同源的 URL 之间进行资源的交互。

Snipaste_2022-05-05_20-02-37.png

跨域:

跨域与同源刚好相反

Snipaste_2022-05-05_20-04-54.png

破浏览器跨域限制的两种方案

JSONP 和 CORS (CORS 是跨域的主流)

方案诞生的时间方案来源优点缺点
JSONP出现较早民间(非官方)兼容性好(兼容低版本 IE)仅支持 GET 请求
CORS出现较晚W3C 官方标准支持 GET、POST、PUT、DELETE、PATCH等常见的请求方式不兼容某些低版本浏览器

CORS 的概念

CORS 是解决跨域数据请求的终极解决方案,全称是 Cross-origin resource sharing。 CORS 技术需要浏览器和服务器同时支持,二者缺一不可:

  1. 浏览器要支持 CORS 功能(主流的浏览器全部支持,IE 不能低于 IE10)
  2. 服务器要开启 CORS 功能(需要后端开发者为接口开启 CORS 功能)

CORS 的原理

服务器端通过 Access-Control-Allow-Origin 响应头,来告诉浏览器当前的 API 接口是否允许跨域请求。

Snipaste_2022-05-05_20-07-21.png

防抖 & 节流

防抖:

防抖(debounce)指的是:频繁触发某个操作时,只执行最后一次。

Snipaste_2022-05-05_20-09-02.png

Snipaste_2022-05-05_20-09-37.png

节流:

节流(throttle)指的是:单位时间内,频繁触发同一个操作,只会触发 1 次。

Snipaste_2022-05-05_20-10-14.png

Snipaste_2022-05-05_20-10-33.png \