前端进行HTTP请求的要点
- 传入基本参数(
url
,请求方式) - 请求参数、请求参数类型
- 设置请求头
- 获取响应的方式
- 获取响应头、响应状态、响应结果
- 异常处理
- 携带
cookie
设置 - 跨域请求
前端进行HTTP请求的方式
form
表单、ifream
、刷新页面Ajax
- 异步网络请求的开山鼻祖jQuery
- 一个时代fetch
-Ajax
的替代者axios、request
等众多开源库
form
最原始的一种http请求的方式
1 | <FORM method="post" action="http://w.sohu.com" > |
Ajax
Ajax的出现解决了什么问题
在Ajax
出现之前,web
程序是这样工作的:
这种交互的的缺陷是显而易见的,任何和服务器的交互都需要刷新页面,用户体验非常差,Ajax
的出现解决了这个问题。Ajax
全称Asynchronous JavaScript + XML
(异步JavaScript
和XML
)
使用Ajax
,网页应用能够快速地将增量更新呈现在用户界面上,而不需要重载(刷新)整个页面。
Ajax
本身不是一种新技术,而是用来描述一种使用现有技术集合实现的一个技术方案,浏览器的XMLHttpRequest
是实现Ajax
最重要的对象(IE6
以下使用ActiveXObject
)。
尽管X
在Ajax
中代表XML
, 但由于JSON
的许多优势,比如更加轻量以及作为Javascript
的一部分,目前JSON
的使用比XML
更加普遍。
原生Ajax
这里主要分析XMLHttpRequest
对象,下面是它的一段基础使用:
1 | var xhr = new XMLHttpRequest(); |
下面分别对XMLHttpRequest
对象常用的的函数、属性、事件进行分析。
函数
open
用于初始化一个请求,用法:
1 | xhr.open(method, url, async); |
method
:请求方式,如get、post
url
:请求的url
async
:是否为异步请求
send
用于发送HTTP
请求,即调用该方法后HTTP
请求才会被真正发出,用法:
1 | xhr.send(param) |
param
:http请求的参数,可以为string、Blob
等类型。
abort
用于终止一个ajax
请求,调用此方法后readyState
将被设置为0
,用法:
1 | xhr.abort() |
setRequestHeader
用于设置HTTP
请求头,此方法必须在open()
方法和send()
之间调用,用法:
1 | xhr.setRequestHeader(header, value); |
getResponseHeader
用于获取http
返回头,如果在返回头中有多个一样的名称,那么返回的值就会是用逗号和空格将值分隔的字符串,用法:
1 | var header = xhr.getResponseHeader(name); |
属性
readyState
用来标识当前XMLHttpRequest
对象所处的状态,XMLHttpRequest
对象总是位于下列状态中的一个:
值 | 状态 | 描述 |
---|---|---|
0 | UNSENT |
代理被创建,但尚未调用 open() 方法。 |
1 | OPENED |
open() 方法已经被调用。 |
2 | HEADERS_RECEIVED |
send() 方法已经被调用,并且头部和状态已经可获得。 |
3 | LOADING |
下载中; responseText 属性已经包含部分数据。 |
4 | DONE |
下载操作已完成。 |
status
表示http
请求的状态, 初始值为0
。如果服务器没有显式地指定状态码, 那么status
将被设置为默认值, 即200
。
responseType
表示响应的数据类型,并允许我们手动设置,如果为空,默认为text
类型,可以有下面的取值:
值 | 描述 |
---|---|
"" |
将 responseType 设为空字符串与设置为"text" 相同, 是默认类型 (实际上是 DOMString )。 |
"arraybuffer" |
response 是一个包含二进制数据的JavaScript ArrayBuffer 。 |
"blob" |
response 是一个包含二进制数据的 Blob 对象 。 |
"document" |
response 是一个HTML Document 或XML XMLDocument ,这取决于接收到的数据的 MIME 类型。 |
"json" |
response 是一个 JavaScript 对象。这个对象是通过将接收到的数据类型视为JSON 解析得到的。 |
"text" |
response 是包含在DOMString 对象中的文本。 |
response
返回响应的正文,返回的类型由上面的responseType
决定。
withCredentials
ajax
请求默认会携带同源请求的cookie
,而跨域请求则不会携带cookie
,设置xhr
的withCredentials
的属性为true
将允许携带跨域cookie
。
事件回调
onreadystatechange
1 | xhr.onreadystatechange = callback; |
当readyState
属性发生变化时,callback会被触发。
onloadstart
1 | xhr.onloadstart = callback; |
在ajax
请求发送之前(readyState==1
后, readyState==2
前),callback
会被触发。
onprogress
1 | xhr.onprogress = function(event){ |
回调函数可以获取资源总大小total
,已经加载的资源大小loaded
,用这两个值可以计算加载进度。
onload
1 | xhr.onload = callback; |
当一个资源及其依赖资源已完成加载时,将触发callback
,通常我们会在onload
事件中处理返回值。
异常处理
onerror
1 | xhr.onerror = callback; |
当ajax
资源加载失败时会触发callback
。
ontimeout
1 | xhr.ontimeout = callback; |
当进度由于预定时间到期而终止时,会触发callback
,超时时间可使用timeout
属性进行设置。
jQuery
jQuery将原生的ajax进行了封装,使使用更加简洁
在很长一段时间里,人们使用
jQuery
提供的ajax
封装进行网络请求,包括$.ajax、$.get、$.post
等,这几个方法放到现在,依然很实用
1 | $.ajax({ |
$.ajax
只接收一个参数,这个参数接收一系列配置,其自己封装了一个jqXHR
对象,有兴趣可以阅读一下jQuary-ajax 源码
常用配置
url
当前页地址。发送请求的地址。
type
类型:String
请求方式 ("POST"
或"GET"
), 默认为 "GET"
。注意:其它HTTP
请求方法,如PUT
和 DELETE
也可以使用,但仅部分浏览器支持。
timeout
类型:Number
设置请求超时时间(毫秒)。此设置将覆盖全局设置。
success
类型:Function
请求成功后的回调函数。
jsonp
在一个jsonp
请求中重写回调函数的名字。这个值用来替代在"callback=?"
这种GET
或POST
请求中URL
参数里的"callback"
部分。
error 类型:Function
。请求失败时调用此函数。
注意:源码里对错误的判定:
1 | isSuccess = status >= 200 && status < 300 || status === 304; |
返回值除了这几个状态码都会进error
回调。
dataType
1 | "xml": 返回 XML 文档,可用 jQuery 处理。 |
data
类型:String
使用JSON.stringify
转码
complete
类型:Function
请求完成后回调函数 (请求成功或失败之后均调用)。
async
类型:Boolean
默认值:true
。默认设置下,所有请求均为异步请求。如果需要发送同步请求,请将此选项设置为 false
。
contentType
类型:String
默认值: "application/x-www-form-urlencoded"
。发送信息至服务器时内容编码类型。
键值对这样组织在一般的情况下是没有什么问题的,这里说的一般是,不带嵌套类型JSON
,也就是 简单的JSON
,形如这样:
1 | { |
但是在一些复杂的情况下就有问题了。 例如在 Ajax
中你要传一个复杂的 json
对像,也就说是对象嵌数组,数组中包括对象,你这样传:application/x-www-form-urlencoded
这种形式是没有办法将复杂的JSON
组织成键值对形式。
1 | { |
可以用如下方式传递复杂的json
对象
1 | $.ajax({ |
Axios
axios
基于Promise
对原生的XHR
进行了非常全面的封装,使用方式也非常的优雅。另外,axios
同样提供了在node
环境下的支持,可谓是网络请求的首选方案
具体详情请见:
POST请求
使用axios发送post请求主要有下面三种方式
- Content-Type: application/x-www-form-urlencoded
- Content-Type: multipart/form-data
- Content-Type: application/json
fetch
Fetch API
是一个用用于访问和操纵HTTP管道的强大的原生 API。这种功能以前是使用 XMLHttpRequest实现的。Fetch提供了一个更好的替代方法,可以很容易地被其他技术使用,例如 Service Workers。Fetch还提供了单个逻辑位置来定义其他HTTP相关概念,例如CORS和HTTP的扩展。
可见fetch是作为XMLHttpRequest的替代品出现的。
使用fetch
,你不需要再额外加载一个外部资源。但它还没有被浏览器完全支持,所以你仍然需要一个polyfill
。
使用方式:https://segmentfault.com/a/1190000018668190#articleHeader11
参考: