深入理解http

一、HTTP 简介

HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送协议。

通俗讲:一套用来规范网页和服务器通信行为的一种协议。

HTTP是一个基于TCP/IP通信协议来传递数据(HTML 文件, 图片文件, 查询结果等)。

二、客户端请求消息

客户端发送一个HTTP请求到服务器的请求报文包括以下格式:请求行(request line)、请求头(header)、空行、请求体四个部分组成

请求行:由请求Method, URL 字段和HTTP Version三部分构成, 总的来说请求行就是定义了本次请求的请求方式, 请求的地址, 以及所遵循的HTTP协议版本

请求头:由一系列的键值对组成,允许客户端向服务器端发送一些附加信息或者客户端自身的信息
img
请求体:只有在发送POST请求时才会有请求体(请求参数),GET方法并没有请求体

三、服务器响应消息

HTTP响应也由四个部分组成,分别是:状态行、响应头、空行、响应体

状态行:也由三部分组成,包括HTTP协议的版本,状态码,以及对状态码的文本描述。

响应头:由一系列的键值对组成,用于描述服务器的基本信息,以及数据的描述,服务器通过这些数据的描述信息,可以通知客户端如何处理等一会儿它响应回来的数据。
在这里插入图片描述
响应体:响应回来的内容

四、请求content-type的组成:type/subtype;parameter;

例如 Content-Type: text/html;charset:utf-8;

主类型type
  • text---------------文本类型
  • application---- 应用类型
  • *-------------------所有类型
子类型subtype
  • html-----------html格式
  • xml -----------xml格式
  • json-----------json格式
  • *---------------所有格式
参数parameter

常用的是编码方式参数---------charset:utf-8

常见的媒体类型

type/subtype 即是互联网媒体类型,也叫作MIME-Type

主类型是text

text/html : HTML格式
text/plain :纯文本格式      
text/xml :  XML格式(忽略xml头所指定编码格式而默认采用us-ascii编码)
image/png: png图片格式

主类型是application

application/xhtml+xml :XHTML格式
application/xml       : XML数据格式(根据xml头指定的编码格式来编码)
application/json      : JSON数据格式
application/octet-stream   : 二进制流数据(如常见的文件下载)
application/x-www-form-urlencoded   :表单上传的数据编码格式

特殊类型

multipart/form-data   :上传文件等二进制的数据编码格式

Post请求的两种编码格式:application/x-www-form-urlencoded和multipart/form-data

application/x-www-form-urlencoded(浏览器默认的编码格式)表单提交:

在Chrome的开发者工具中可以看出,表单上传编码格式为application/x-www-form-urlencoded(Request Headers中),参数的格式为key=value&key=value
在这里插入图片描述
我们可以看出,服务器知道参数用符号&间隔,如果参数值中需要&,则必须对其进行编码。编码格式就是application/x-www-form-urlencoded将键值对的参数用&连接起来,如果有空格,将空格转换为+加号;有特殊符号,将特殊符号转换为ASCII HEX值)。

对于Get请求,是将参数转换?key=value&key=value格式,连接到url后

multipart/form-data文件上传:

在Chrome的开发者工具中可以看出multipart/form-data不会对参数编码,而是使用boundary(分割线),相当于&,boundary的值等于 ----WebkitFormBoundry****
在这里插入图片描述

五、请求content-type的三种设置方式
1.设置在发送请求页面的header中
<header>
  <meta content="text/html" charset="utf-8"/>
</header>

不能指定application/x-www-form-urlencoded和multipart/form-data这两种类型

2.设置在form表单提交的enctype参数中
<form action="" enctype="multipart/form-data"></form>
<form action="" enctype="application/x-www-form-urlencoded"></form>

只能指定application/x-www-form-urlencoded和multipart/form-data这两种类型
默认是application/x-www-form-urlencoded类型,浏览器会把表单中发送的数据编码为“key=value”对的形式
当向服务器发送大量的文本、包含非ASCII字符的文本或二进制数据时,例如上传文件时,选择multipart/form-data

3.设置在request header参数中
  var formData = new FormData();
  formData.append('username', 'johndoe');
  formData.append('id', 123456);
  // 1.创建xhr对象 
  var xhr = new XMLHttpRequest();
  //设置xhr请求的超时时间
  xhr.timeout = 3000;
  //设置响应返回的数据格式-------------------重点
  xhr.responseType = "text";
  // 2.创建一个 post 请求,采用异步
  xhr.open('POST', '/server', true);
  // 3.设置请求头--------------------------重点
  xhr.setRequestHeader('Content-Type', 'multipart/form-data');
  // 4.发送请求---------------------------重点
  xhr.send(formData);
  // 5.注册相关事件回调处理函数
  xhr.onload = function(e) { 
    if(this.status == 200||this.status == 304){
        alert(this.responseText);
    }
  };

没有限制都可以用
xhr.send(data)中data参数的数据类型会影响请求头部content-type的默认值,
如果用xhr.setRequestHeader()手动设置了中content-type的值,以上默认值就会被覆盖。

xhr.send(data)的参数data可以是以下几种类型:
  • ArrayBuffer
  • Blob
  • Document
  • DOMString
  • FormData
  • null

详解:xhr.send(data),data可以是什么类型的数据:https://blog.csdn.net/lcrxxoo/article/details/70842396

DOMString

实际上就是XMLHttpRequest中数据返回属性之responseText,在JavaScript中,DOMString就是String。规范解释说DOMString指的是UTF-16字符串,而JavaScript正是使用了这种编码的字符串,因此,在Ajax中,DOMString就等同于JS中的普通字符串。

Document数据类型

实际上就是XMLHttpRequest中数据返回属性之responseXML,也就是可以解析为XML的数据。因此,这里的Document数据类似你就可以近似看成XML数据类型。

FormData对象

我们应该都用过jQuery,其中有个方法叫做serialize(), 作用就是表单序列化,也就是以查询字符串形式获得类表单post/get的数据给Ajax请求,例如:userid=123&username=zxx.

FormData对象的作用就类似于这里的serialize()方法,不过FormData是浏览器原生的,且支持二进制文件,是个一眼就会让人喜欢的很赞的东西!

Blob数据对象

实际上,Blob是计算机界通用术语之一,全称写作:BLOB (binary large object),表示二进制大对象。MySql/Oracle数据库中,就有一种Blob类型,专门存放二进制数据。

在实际Web应用中,Blob更多是图片二进制形式的上传与下载,虽然其可以实现几乎任意文件的二进制传输。

举个例子,使用Blob从服务器下载.excel文件

exportExcel(pageStore, exportUrl, filters, name, suffix) {
            this.$store.commit('global/ISLOADING', true);
            let nowData = date(this.nowTime).replace(/-/g, '');
            let time = 0;
            this.timer = setInterval(() => {
                time++;
                console.log('---nn-------', time);
                if (time >= 120) {
                    this.$store.commit('global/ISLOADING', false);
                    this.cancelQuest(this.source);
                    this.$message.warning('导出超时,请重试!');
                    clearInterval(this.timer);
                }
            }, 1000);
            this.$store.dispatch(`${pageStore}/${exportUrl}`, filters)
                .then((res) => {
                    if (!this.isLoading || !res) return false;
                    clearInterval(this.timer);
                    this.$store.commit('global/ISLOADING', false);
                    if (res.type === 'application/json') {
                        let reader = new FileReader();
                        reader.readAsText(res, ['utf-8']);
                        reader.onloadend = () => {
                            let obj = JSON.parse(reader.result);
                            this.$message.warning(obj.msg);
                        };
                    } else {
                        let blob = new Blob([res], {
                            type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.shee;charset-UTF-8'
                        });
                        let url = URL.createObjectURL(blob);
                        const a = document.createElement('a');
                        a.style.display = 'none';
                        let suffixName = suffix || '.xlsx';
                        a.download = `${name}${nowData}${suffixName}`;
                        a.href = url;
                        document.body.appendChild(a);
                        a.click();
                        document.body.removeChild(a);
                    }
                });
        },
    
// 导出全部线索列表api
export const exportAllClue = (params = {}, that) => Vue.ajax.post('/xxxxx/xxxxxx/downAllClue', params, {
    responseType: 'blob',
    cancelToken: new axios.CancelToken(function executor(c) {
        that.source = c;
    })
});
//页面调用
this.exportExcel();

构造函数:Blob() 构造函数返回一个新的 Blob 对象。

let blog = new Blob(array, options);

array 是一个由ArrayBuffer, ArrayBufferView, Blob, DOMString 等对象构成的 Array ,或者其他类似对象的混合体,它将会被放进 Blob。DOMStrings会被编码为UTF-8。

options 一个对象,设置Blob对象的一些属性。目前仅支持 typesize属性。

type默认值为 “”,它代表了将会被放入到blob中的数组内容的MIME类型。

size表示Blob对象包含数据的字节大小。

方法: slice()可以实现文件的分割!

ArrayBuffer对象

很术语的解释有:

ArrayBuffer表示二进制数据的原始缓冲区,该缓冲区用于存储各种类型化数组的数据。

ArrayBuffer是二进制数据通用的固定长度容器。

通俗语解释:所谓ArrayBuffer就是个装着2进制数据的对象。或者想象成带了个名叫“缓冲”帽子的二进制数据。然后直接关联:ArrayBuffer = 2进制

BlobArrayBuffer有啥区别呢?

Blob可以append ArrayBuffer数据,也就是Blob是个更高一级的大分类,类似领导的感觉。ArrayBuffer则是具有某种恶魔果实的尖兵。

ArrayBuffer存在的意义就是作为数据源提前写入在内存中,就是提前钉死在某个区域,长度也固定,万年不变。于是,当我们要处理这个ArrayBuffer中的二进制数据,例如,分别8位,16位,32位转换一遍,这个数据都不会变化,3种转换共享数据。

So,ArrayBuffer就是缓冲出来的打死不动的二进制对象。

注意,ArrayBuffer本身是不能读写的,需要借助类型化数组或DataView对象来解释原始缓冲区(宰割原始二进制数据)。

类型化数组
类型化数组(Typed Arrays)是JavaScript中新出现的一个概念,专为访问原始的二进制数据而生。

类型数组的类型有:在这里插入图片描述
本质上,类型化数组和ArrayBuffer是一样的。不过一个可读写(脱掉buffer限制),一个当数据源的命。

六、响应responseType

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值