一般使用XHR进行异步访问、获取资源会有以下几个步骤:
创建对象、设置请求函数和回调函数、获取异步对象的readyState属性、判断响应报文的状态、读取响应数据。
var xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", "/try/ajax/demo_get.php", true);
/*xmlhttp.onload = () => { // 响应的状态码为4
var data = JSON.parse(this.responseText);
console.log(data);
}*/
xmlhttp.onerror = () => {
console.log(err);
}
xmlhttp.send();
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
document.getElementById("mydiv").innerHTML = xmlhttp.responseText;
}
}
-
状态码
0:请求未初始化
1:服务器连接已建立
2:请求已接受
3:请求已处理
4:请求已完成,且响应已就绪
状态码为2、3和4时进入onreadystatechange,而对于onload,只有状态码为4才能进入。
-
实现加载请求中相关——
onprogressfunction loadText(){ let xhr = new XMLHttpRequest(); xhr.open('GET','sample.txt',true); console.log("READYSTATE"+ xhr.readyState); // 1 //两种请求方式onload和onreadystatechange xhr.onprogress = function(){ console.log("测试加载状态READYSTATE"+ xhr.readyState); // 3 } xhr.onload = function(){ console.log("READYSTATE"+ xhr.readyState); //4 console.log(this.responseText); } xhr.send(); }
Fetch
使用语法
fetch是基于promise的,fetch方法必须接受一个参数——资源的路径URL,返回一个promise对象,resolve对应请求的response。
fetch(url,options).then((response)=>{
//处理http响应
},(error)=>{
//处理错误
})
options:发送请求参数,
body-http请求参数mode- 指定请求模式。默认值为cros:允许跨域;same-origin:只允许同源请求;no-cros:只限于get、post和head,并且只能使用有限的几个简单标头。cache- 用户指定缓存。method- 请求方法,默认GETsignal- 用于取消fetchheaders-http请求头设置keepalive- 用于页面卸载时,告诉浏览器在后台保持连接,继续发送数据。credentials - cookie设置,默认omit,忽略不带cookie,same-origin同源请求带cookie,inclue无论跨域还是同源都会带cookie。
读取内容方法
fetch请求成功后会获取到response响应对象:
status-http状态码,范围在100-599之间statusText- 服务器返回状态文字描述ok- 返回布尔值,如果状态码2开头的,则true,反之falseheaders- 响应头body- 响应体。响应体内的数据,根据类型各自处理。type- 返回请求类型。redirected- 返回布尔值,表示是否发生过跳转。
response对象对于服务器返回的不同类型的数据有着不同的读取方法,并且这些方法都返回一个promise对象:
response.text()-- 得到文本字符串response.json()- 得到json对象response.blob()- 得到二进制blob对象response.formData()- 得到formData表单对象response.arrayBuffer()- 得到二进制arrayBuffer对象
get请求和post请求
-
get请求// 通过fetch获取百度的错误提示页面 fetch('https://www.baidu.com/search/error.html?a=1&b=2', { // 在URL中写上传递的参数 method: 'GET' // 默认为get }) .then((res)=>{ return res.text() }) .then((res)=>{ console.log(res) }) -
post请求// 通过fetch获取百度的错误提示页面 fetch('https://www.baidu.com/search/error.html', { method: 'POST', headers: new Headers({ 'Content-Type': 'application/x-www-form-urlencoded' // 指定提交方式为表单提交 }), body: new URLSearchParams([["foo", 1],["bar", 2]]).toString() }) .then((res)=>{ return res.text() }) .then((res)=>{ console.log(res) })post请求的参数为了防止信息泄露时不能放在URL中的。post请求默认的提交方式是Content-Type:text/plain;charset=UTF-8,但我们一般使用表单提交,所以我们可以指定头信息为application/x-www-form-urlencoded。
cookie相关
fetch在默认情况下是不会从服务端接收任何cookies的,要发送cookies的话就必须发送凭据头。
// 通过fetch获取百度的错误提示页面
fetch('https://www.baidu.com/search/error.html', {
method: 'GET',
credentials: 'include' // 强制加入凭据头
})
.then((res)=>{
return res.text()
})
.then((res)=>{
console.log(res)
})
封装fetch
/**
* 将对象转成 a=1&b=2的形式
* @param obj 对象
*/
function obj2String(obj, arr = [], idx = 0) {
for (let item in obj) {
arr[idx++] = [item, obj[item]]
}
return new URLSearchParams(arr).toString()
}
/**
* 真正的请求
* @param url 请求地址
* @param options 请求参数
* @param method 请求方式
*/
function commonFetcdh(url, options, method = 'GET') {
const searchStr = obj2String(options)
let initObj = {}
if (method === 'GET') { // 如果是GET请求,拼接url
url += '?' + searchStr
initObj = {
method: method,
credentials: 'include'
}
} else {
initObj = {
method: method,
credentials: 'include',
headers: new Headers({
'Accept': 'application/json',
'Content-Type': 'application/x-www-form-urlencoded'
}),
body: searchStr
}
}
fetch(url, initObj).then((res) => {
return res.json()
}).then((res) => {
return res
})
}
/**
* GET请求
* @param url 请求地址
* @param options 请求参数
*/
function GET(url, options) {
return commonFetcdh(url, options, 'GET')
}
/**
* POST请求
* @param url 请求地址
* @param options 请求参数
*/
function POST(url, options) {
return commonFetcdh(url, options, 'POST')
}
// 例子
GET('https://www.baidu.com/search/error.html', {a:1,b:2})
POST('https://www.baidu.com/search/error.html', {a:1,b:2})