堪比ajax的高频请求和响应新方式——fetch(前端分页项目应用)

又是一周最好时… 周末了,聊点轻松的话题:一周的总结与复习。
早上看到以前的笔记,突然看到了fetch,当时就很懵逼,我怎么不记得这东西了。。。故写此文章,纪念一下。

fetch API

它提供了一个JavaScript接口,用于访问和操纵HTTP管道的部分,例如:请求和响应。
它还提供了一个 全局的fetch()方法 ,该方法提供了一种简单、合理的方式来 跨网络异步获取资源
这种功能以前是使用XMLHttpReauest实现的。fetch提供了一个更好的替代方法,可以很轻松的被其他技术,如 Service Workers 所引用。
除此,fetch还提供了单个逻辑位置来定义其它HTTP相关概念,例如:CORS和HTTP的扩展。

fetch的基本格式

fetch(url地址,如:'http://example.com/movies.json')
	.then(function(response){
		//数据响应信息,接收后端传来的数据,return 传给下面的.then处理(Promise链式表示法)
		return response.json();
	})
	.then(function(变量接收return的数据,如:myJson){
		//执行操作
		console.log(myJson);
	})

fetch在vue项目中的应用

我写过一个 分页数据加载与展示 的功能页面,下面来据此分析一下:
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代码也可以看出:只有到滑到底部的时候,才去 动态加载 “下一页”的内容。

现在我们有了后端传来的数据接口和参数了:
堪比ajax的高频请求和响应新方式——fetch(前端分页项目应用)_第1张图片
怎么用?

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的其他应用

当然了,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与“跨域”

以前写过关于 跨域 的文章,但是太过“模糊”,这里对于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()是有区别的:

  • 当接收到一个代表错误的http状态码时,从fetch()返回的Promise 不会被标记为reject ,即使该http响应的状态码是404或500。相反,它会将Promise状态标记为resolve(但是会把resolve的返回值的ok属性设置为false),仅当网络故障或请求被阻止时,才会标记reject。
  • 默认情况下,fetch 不会从服务端发送或接收任何cookies ,如果站点依赖于用户session,则会导致未经认证的请求。

你可能感兴趣的:(实战vue:由浅入深,透彻解读)