又是一周最好时… 周末了,聊点轻松的话题:一周的总结与复习。
早上看到以前的笔记,突然看到了fetch,当时就很懵逼,我怎么不记得这东西了。。。故写此文章,纪念一下。
它提供了一个JavaScript接口,用于访问和操纵HTTP管道的部分,例如:请求和响应。
它还提供了一个 全局的fetch()方法 ,该方法提供了一种简单、合理的方式来 跨网络异步获取资源 。
这种功能以前是使用XMLHttpReauest实现的。fetch提供了一个更好的替代方法,可以很轻松的被其他技术,如 Service Workers 所引用。
除此,fetch还提供了单个逻辑位置来定义其它HTTP相关概念,例如:CORS和HTTP的扩展。
fetch(url地址,如:'http://example.com/movies.json')
.then(function(response){
//数据响应信息,接收后端传来的数据,return 传给下面的.then处理(Promise链式表示法)
return response.json();
})
.then(function(变量接收return的数据,如:myJson){
//执行操作
console.log(myJson);
})
我写过一个 分页数据加载与展示 的功能页面,下面来据此分析一下:
HTML
<div id="app" v-cloak>
<div class="scroll-container">
<div v-for="o in data" style="border: 1px solid #eee">
<div style="padding: 10px;">
<h3>{{o.title}}</h3>
<p>{{o.body}}</p>
</div>
</div>
</div>
<div style="text-align: center;">
<div v-if="isLoading">Loading</div>
</div>
</div>
前面div的v-for:以更简单的方式展示大量有相同特点的数据项。o指代了每一项的数据——这一点从下面 {{}}动态绑定 的{{o.title}}
和{{o.body}}
也可以看出。
这里可以体现出vue和微信小程序的不同之处:
vue的v-for中用双引号"",必须指定o(或什么)来知道其中某一项;
而小程序中用"{{}}",括号中只需放(要循环的)数组,自带了一个item,可直接调用
下面的Loading中为何要放v-if属性?
通过下面的js代码也可以看出:只有到滑到底部的时候,才去 动态加载 “下一页”的内容。
JS
new Vue({
el:'#app',
data:{
pageNo:0,
pageSize:7,
url:"http://127.0.0.1:3000/news/page/",
data:[],
isLoading:false
},
created(){
this.loadData(this.pageNo,this.pageSize);
window.onscroll=function () {
this.endOfTheScreen=this.scrollCheck();
}
},
//监听页面数据变化
watch:{
endOfTheScreen(newValue){
if(newValue){
this.pageNo++;
this.loadData(this.pageNo,this.pageSize);
}
}
},
methods:{
scrollCheck(){
var winHeight=window.scrollY+window.innerHeight;
//下面 document.documentElement.offsetHeight是指页面中(所有)有内容(部分)(即文档流)的高度
return winHeight===document.documentElement.offsetHeight;
},
loadData(pageNo,pageSize){
this.isLoading=true;
//fetch括号里要求是个url!下面这样写是为了拼接参数——从第几页展示,每页展示几个数据项
fetch(this.url+pageNo+"/"+pageSize)
.then(res=>{
if(res.ok){
return res.json();
}else{
return Promise.reject({
status:response.status,
statusText:response.statusText
});
}
})
.then((res=>{
for(let i in res.data){
this.data.push(res.data[i]);
}
this.isLoading=false;
}))
.catch(e=>{
console.log('status: '+e.status);
console.log('statusText: '+e.statusText);
});
}
}
})
css
[v-cloak]{display:none;}
.scroll-container{width: 80%;margin: 0 auto;}
当然了,fetch也不是只能用在vue中,例如 我们可以用如下方式发一个post请求:
(body和headers是区分fetch中post和get请求的方式)
fetch('http://127.0.0.1:3000/news/page/', {
method: 'POST',
body: JSON.stringify({
name: "mxc",
age: 18
}),
headers: {
"Content-type": "application/json; charset=UTF-8"
}
})
.then(response => {response.json()})
.then(json => {console.log(json)})
对,vue的这两种请求方式(axios/fetch),都不支持发送“对象”!
以前写过关于 跨域 的文章,但是太过“模糊”,这里对于fetch“就事论事”:
cors:
cors是"Cross-Origin Resource Sharing"的简称,是实现跨域的一种方式,相对于其他跨域方式,比较灵活,而且不限制发请求使用的method
其实跨域问题算是前后端共同的问题,比如对于fetch,前端只需在其中加一个属性:mode :
fetch('http://localhost:6888/test_get',{
method: 'GET',
mode: 'cors',
}).then(res => {
return res.json();
}).then(json => {
console.log('获取的结果', json.data);
return json;
}).catch(err => {
console.log('请求错误', err);
})
后端配置代码:
c.Header("Access-Control-Allow-Origin", "*")
c.Header("Access-Control-Allow-Methods", "GET, POST")
而post请求如下:其后端配置和上面代码相同:
fetch('http://localhost:6888/test_post',{
method: 'POST',
body: JSON.stringify({name: 'zaozuo'}),
mode: 'cors',
}).then(res => {
return res.json();
}).then(json => {
console.log('获取的结果', json.data);
return json;
}).catch(err => {
console.log('请求错误', err);
})
需要注意的是,fetch规范与jQuery.ajax()是有区别的: