记录一些前端知识
Ajax
Ajax : Asynchronous·+ XML缩写,能够向服务器额外请求数据而不须卸载页面。Ajax的核心为XMLHttpRequest(XHR)
创建一个xhr对象
因为IE5是第一款引入XHR对象的浏览器,在IE5中,XHR是通过MSXML库中的ActiveX对象实现的,所以在IE浏览器中,XHR有三个不同的版本:MSXML2.XMLHttp、MSXML2.XMLHttp.3.0、MSXML2.XMLHttp.6.0
复制代码
//对于IE7版本之前
function createXHR(){
if(typeof agruments.callee.activeXString!='string'){
var versions = ["MSXML2.XMLHttp","MSXML2.XMLHttp.3.0","MSXML2.XMLHttp.6.0"],i,len;
for(i=0;len = versions.length;itry{
new ActiveXObject(versions[i])
agruments.callee.activeXString = version[i];
}catch(ex){
}
}
}
return new ActiveXObject(agruments.callee.activeXString);
}
//对于IE7+、Firefox、Opera、Chrome、Safari支持原生的XHR对象
var xhr = new XMLHttpRequest();
复制代码
总结上面情况
function createXHR(){
if(typeof XMLHttpRequest!='undefined'){
return new XMLHttpRequest();
}else if(typeof ActiveXObject!='undefined'){
if(typeof agruments.callee.activeXString!='string'){
var versions = ["MSXML2.XMLHttp","MSXML2.XMLHttp.3.0","MSXML2.XMLHttp.6.0"],i,len;
for(i=0;len = versions.length;itry{
new ActiveXObject(versions[i])
agruments.callee.activeXString = version[i];
}catch(ex){
}
}
}
return new ActiveXObject(agruments.callee.activeXString);
}else{
throw new Error("No XHR object available");
}
}
var xhr = createXHR();
复制代码
XHR的用法
(1)open():接受三个参数:请求类型,请求url,是否异步发送请求的布尔值。
//调用open不会发送请求,只是启动了一个请求以备发送
xhr.open("get",url,false);
复制代码
- GET:用于获取资源
- HEAD:与get方法类似,但是不返回message body 内容,返回HTTP头信息
- POST:向服务器提交数据
- DELETE:删除资源
- PUT:与POST相似,但是PUT指定资源存放位置,但是POST由服务器自己决定
- OPTIONS:用于获取当前URL所支持的方法。若请求成功,则它会在HTTP头中包含一个名为“Allow”的头,值是所支持的方法,如“GET, POST”
(2)send():接受一个参数,作为请求主体发送的数据,如果不需要,则必须传入null。调用send后请求会分派到服务器
(3)readyState:表示请求/响应过程的当前活动阶段
0 :未初始化,没有调用open()方法
1 :启动,调用open()方法,没有调用send()
2 :发送,调用send,但没有收到响应
3 :接收,收到部分响应数据
4 :完成,接收全部响应数据,而且可以在客户端使用
复制代码
(4)onreadystatechange():因为readyState属性值由一个变成另外一个值,都会触发onreadystatechange,可以利用该事件检验readyState的值,必须在open()之前使用
var xhr = createXHR();
xhr.onreadystatechange = function(){
if(xhr.readyState ==4){
if((xhr.status>=200&&xhr.status<300)||xhr.status==304){
console.log(xhr.reponseText)
}else{
console.log("Request was unsuccessful: "+xhr.status);
}
}
}
xhr.open("get",url,true);
xhr.send(null);
复制代码
在浏览器收到服务器响应后,响应数据会自动填充到XHR对象的属性中:
- responseText :作为响应主体被返回的文本
- responseXML:如果响应的内容类型是“text/xml”或“application/xml”,这个属性中将保存包含着响应数据的XML DOM文档
- status:响应的HTTP状态
- statusText:HTTP状态的说明》
(4) Http头部信息
- accept:浏览器能够处理的内容类型
- accept-charset:浏览器能够显示的字符集
- accept-encoding:浏览器能够处理的压缩编码
- accept-language:浏览器当前设置的语言
- connection:浏览器与服务器之间连接的类型
- cookie:当前页面设置的任何cookie
- host:发送请求的页面所在的域
- referer:发送请求的页面的url
- user-agent:浏览器的用户代理字符串
使用sendRequestHeader()方法可以设置自定义的请求头部信息,但是必须在open之后send之前使用
xhr.open("get",url,true);
xhr.sendRequestHeader("Content-Type","application/x-www-form-unlecoded");
xhr.send(null);
复制代码
(5)超时设定 timeout
xhr.open("get",url,true);
xhr.sendRequestHeader("Content-Type","application/x-www-form-unlecoded");
xhr.timeout = 1000;
xhr.send(null);
复制代码
优点: 1.无刷新更新数据 2.异步与服务器通信 3.前后端负载平衡
缺点:1.AJAX干掉了Back和History功能,即对浏览器机制的破坏。 2.AJAX的安全问题。
$.ajax
该方法是 jQuery 底层 AJAX 实现。简单易用的高层实现见
$.get
,$.post
等。$.ajax() 返回其创建的 XMLHttpRequest 对象。
jQuery.ajax([settings])
参数:
- url: 发送请求的地址
- async 默认值true,为异步请求
- beforeSend(XHR):Function 发送请求前可修改 XMLHttpRequest 对象的函数,如添加自定义 HTTP 头。如果返回 false 可以取消本次 ajax 请求
- cache:默认值: true,dataType 为 script 和 jsonp 时默认为 false。设置为 false 将不缓存此页面。
- contentType:默认值: "application/x-www-form-urlencoded"。发送信息至服务器时内容编码类型。
- context:这个对象用于设置 Ajax 相关回调函数的上下文。让回调函数内 this 指向这个对象
$.ajax({ url: "test.html", context: document.body, success: function(){
$(this).addClass("done");
}})
复制代码
- data:发送到服务器的数据。将自动转换为请求字符串格式
- error:请求失败时调用此函数
- success:请求成功后的回调函数
$.ajax({
type: "GET",
url: "test.json",
data:data,
dataType: "json",
success: function(data){},
error:function(err){}
});
复制代码
Promise
Promise解决回调地狱问题。
Promise的用法
let promise = new Promise((resolve,reject)=>{
setTimeout(()=>{
let rand = Math.random();
if(rand>0.3){
resolve("大于0.3: "+rand)
}else{
reject("小于0.3: "+rand)
}
},1000)
})
复制代码
利用构造函数模式创建一个对象,即promise._proto_ == Promise.prototype
为true。
Promise构造函数接收一个函数作为参数,该函数接受两个各位的函数resolve,reject为参数。这两个函数分别代表将当前Promise置为fulfilled(解决)和rejected(拒绝)两个状态。
promise只是Promise的一个实例对象,在声明的时候并不会立即执行,而每一个Promise的实例对象都有一个then方法,这个方法就是用来处理之前的异步逻辑的结果。
promise.then(resolve=>{
console.log(resolve)
},reject=>{
console.log(reject)
})
复制代码
then方法也有两个参数,第一个调用resolve函数,第二个调用reject函, 并且Promise的then()方法,then总是会返回一个Promise实例,由此可以一直then().then()...
catch
这个方法其实是then方法的一种特例
.then(null, rejection)
相当于我们不使用then方法的第一个函数,只是用第二个函数;catch函数比较简单,就是用来捕获之前的then方法里面的异常
var promise = new Promise((res,rej)=>{
rej("error123456")
});
promise.then(()=>{
consoel.log(123)
}).catch((err)=>{
console.log(err)
})
//运行结果error123456
复制代码
Promise.all
Promise.all可以将多个Promise实例包装成一个新的Promise实例。成功的时候返回的是一个结果数组,而失败的时候则返回最先被reject失败状态的值
let p1 = new Promise((res,rej)=>{
res("success 1");
})
let p2 = new Promise((res,rej)=>{
res("success 2");
})
let p3 = new Promise((res,rej)=>{
rej("error");
})
//["success 1", "success 2"]
Promise.all([p1,p2]).then(success=>{
console.log(success)
}).catch(err=>{
console.log(err)
})
//["success 1", undefined]
Promise.all([p1,p2.p3]).then(success=>{
console.log(success)
}).catch(err=>{
console.log(err)
})
//error
Promise.all([p1,p3,p2]).then((result) => {
console.log(result)
}).catch((error) => {
console.log(error) // 失败了,打出 '失败'
})
复制代码
Promise.race
赛跑,哪个Promise实例获取结果结果快就返回哪个,不管结果本身是成功状态还是失败状态
let p1 = new Promise((res,rej)=>{
setTimeout(()=>{
res("success 1");
},500)
})
let p2 = new Promise((res,rej)=>{
setTimeout(()=>{
res("success 2");
},1000)
})
//success 1
Promise.race([p1,p2]).then((result) => {
console.log(result)
}).catch((error) => {
console.log(error) // 失败了,打出 '失败'
})
复制代码
一个简单的promise的实现
juejin.im/post/5aa786…
ajax+promise
function request(
url: String = "",
method: String = "GET",
data: Object = null,
async: Boolean = true,
headers: Object = {
'content-type': 'application/x-www-form-urlencoded'
}) {
let xhr = new XMLHttpRequest();
method = method.toUpperCase();
xhr.open(method, url, async);
for (let header in headers) {
xhr.setRequestHeader(header, headers[header])
}
xhr.send(method === "GET" ? null : JSON.stringify(data));
return new Promise((resolve, reject) => {
xhr.onreadystatechange = function () {
if (this.readyState === 4) {
if (this.status === 200) {
resolve(JSON.parse(this.responseText), this)
} else {
let resJson = {code: this.status, response: this.response}
reject(resJson, this)
}
}
};
})
}
复制代码
Axios
Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。
使用方法
//get
axios.get('/user?ID=12345')
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
//post
axios.post('/user', {
firstName: 'Fred',
lastName: 'Flintstone'
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
复制代码
axios + promise
import axios from "axios";
let cancel;
const CancelToken = axios.CancelToken;
//请求拦截器
axios.interceptors.request.use(config => {
//一些操作
return config
}, error => {
return Promise.reject(error)
})
//响应拦截器即异常处理
axios.interceptors.response.use(response => {
return response
}, err => {
//...一些操作
return Promise.resolve(err.response)
})
axios.defaults.baseURL = 'XXX'
//设置默认请求头
axios.defaults.headers = {
'X-Requested-With': 'XMLHttpRequest'
}
axios.defaults.timeout = 10000
export default {
//get请求
get(url, param) {
return new Promise((resolve, reject) => {
axios({
method: 'get',
url,
params: param,
cancelToken: new CancelToken(c => {
cancel = c
})
}).then(res => {
//可以根据后端返回status做resolve还是reject
resolve(res)
})
})
},
//post请求
post(url, param) {
return new Promise((resolve, reject) => {
axios({
method: 'post',
url,
data: param,
cancelToken: new CancelToken(c => {
cancel = c
})
}).then(res => {
resolve(res)
})
})
}
}
复制代码