浏览器请求的三种方式
原生XMLHTTPReques
const http =new XMLHTTPRequest()
http.open('Get','http://test/serivce')
http.onreadystatechange=function(){
if(http.readyState!==4)retrun
if(http.status==200){
//获取请求成功后的值
console.log(http.responseText)
}else{
console.log('请求出错')
}
}
//超时处理
//设置超时时间
http.timeout=30000 ///30秒
http.ontimeout=function(){
//超时后的处理函数
}
http.send()
fetch请求
//创建请求取消控制对象
const controller = new AbortController()
fetch(url,{
method:'请求的方式',
credentials:"same-origin"//表示的是同源的请求带cookie
signal:controller.signal //表示的是为请求关联取消控制对象
}).then(response=>{
//请求的成功后失败都在then中进行体现 通过response.ok来判请求是否成功
if(response.ok){
//请求成功
retrun response.json()
}
//失败则抛出异常
throw new Error('请求异常')
}).then(json=>{
}).catch(res=>{
//这里的异常来自与网络异常,fetch执行异常 代码异常 以及throw抛出的异常
})
//请求取消
controller.abort()
fetch中默认是不支持超时处理的,但是因为fetch内部是通过promise去实现的,因此我们可以用promise规范中的 resolve 和reject的状态一旦成为fulfilled或者rejected的状态后就不能改变的特性实现超时
//封装fetch
function myFetch(url,option,timeout){
new promise((resolve,reject)=>{
//将resolve传入 用于promise中then调用获取fetch请求回来的值
fetch(url,option).then(resolve).catch(reject)
//超时后进行promise状态的改变
setTimeout(reject,timeout)
})
}
请求头
referer://请求来自于那个页面
user-ageent//识别用户的操作系统标识
等
相应头
access-control-allpw-origin://跨域
content-encoding//实体头用于压缩媒体类型。
set-cookie//设置cookie
状态码
200// get请求成功
201// post 请求成功
301//永久重定向
302//临时重定向
304//协商缓存 服务器文件未被修改
400 客户端请求有语法错误,不能被服务器识别
403 服务器受到请求,但是拒绝提供服务,可能是跨域
404 请求的资源不存在
405 请求的method不允许
500 服务器发生不可预期的错误
补充
cdn域名和业务域名
所谓的cdn域名可以理解成是资源域名 也就是我们项目中需要获取的资源,单单的职能就是资源的获取比如cdn图片 cdnjs等 所谓的业务域名 可以理解成就是我们数据请求的域名,这些域名一般用户我们业务中的数据请求,身份验证等。
两者之间的区别:
- 安全问题,业务域名中一般都包含用户的新cookie等信息,cdn 不会 2.cdn中只做资源的获取 相对来说带宽的消耗小 业务域名获取数据的时候 header中会带有各个参数消耗的带宽大
3.并发请求数。因为同源的限制如果资源域名和业务域名相同的时候,会造成在请求资源的时候阻塞数据的请求,
ajax的封装
//定义请求的接口
interface options {
url: string,
data?: any,
param?: any,
type: string,
timeout: number
}
//参数处理
function stringQuery(data) {
let stringQueryData = []
for (let key in data) {
stringQueryData.push(`${key}=${data[key]}`)
}
return stringQueryData.join('&')
}
export default function myAjax(option: options) {
let xhr, timer;
//返回一个异步的方法
return new Promise((resolve, reject) => {
//判断当前浏览器是否支持xmlhttprequest 属性
if ((window as any).XMLHttpRequest) {
xhr = new XMLHttpRequest()
} else {
xhr = new ActiveXObject('Microsoft.XMLHTTP')
}
//请求类型的判断
if (option.type.toLocaleUpperCase() === 'GET') {
//第三个参数表示的是 是否异步执行,true表示异步,false 表示同步
xhr.open('get', `${option.url}?${stringQuery(option.param)}`, true)
xhr.send();
} else if (option.type.toLocaleUpperCase() === 'POST') {
xhr.setRequestHeader('ContentType', 'application/x-www-form-urlencoded');
xhr.open('get', option.url, true)
xhr.send(option.data);
}
//请求处理
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
//取消定时器
clearTimeout(timer)
if (xhr.stats >= 200 && xhr.status < 300 || xhr.status === 304) {
resolve(xhr.responseText);
} else {
reject('请求出错')
}
}
}
//超时设置
// xhr.timeout=option.timeout||1000
// xhr.ontimeout=function(){
// reject('请求超时')
// //取消请求
// }
if (option.timeout) {
timer = setTimeout(() => {
//取消请求
xhr.abort()
reject('请求超时')
}, option.timeout)
}
})
}