ajax

 新葡亰Web前端     |      2019-12-07

一、开发流程

前端切完图,处理好接口信息,接着就是把静态demo交给后台去拼接,这是一般的流程。这种流程存在很多的缺陷。

  • 后端同学对文件进行拆分拼接的时候,由于对前端知识不熟悉,可能会搞出一堆bug,到最后又需要前端同学帮助分析原因,而前端同学又不是特别了解后端使用的模板,造成尴尬的局面。
  • 如果前端没有使用统一化的文件夹结构,并且静态资源(如图片,css,js等)没有剥离出来放到 CDN,而是使用相对路径去引用,当后端同学需要对静态资源作相关配置时,又得修改各个link,script标签的src属性,容易出错。
  • 接口问题
    1. 后端数据没有准备好,前端需要自己模拟一套,成本高,如果后期接口有改变,自己模拟的那套数据又不行了。
    2. 后端数据已经开发好,接口也准备好了,本地需要代理线上数据进行测试。这里有两个费神的地方,一是需要代理,否则可能跨域,二是接口信息如果改动,后期接你项目的人需要改你的代码,麻烦。
  • 不方便控制输出。为了让首屏加载速度快一点,我们期望后端先吐出一点数据,剩下的才去 ajax 渲染,但让后端吐出多少数据,我们不好控。

当然,存在的问题远不止上面枚举的这些,这种传统的方式实在是不酷(Kimi 附身^_^)。还有一种开发流程,SPA(single page application),前后端职责相当清晰,后端给我接口,我全部用 ajax 异步请求,这种方式,在现代浏览器中可以使用 PJAX 稍微提高体验,Facebook 早在三四年前对这种 SPA 的模式提出了一套解决方案,quickling+bigpipe,解决了 SEO 以及数据吐出过慢的问题。他的缺点也是十分明显的:

  • 页面太重,前端渲染工作量也大
  • 首屏还是慢
  • 前后端模板复用不了
  • SEO 依然很狗血(quickling 架构成本高)
  • history 管理麻烦

问题多的已经是无力吐槽了,当然他依然有自己的优势,咱们也不能一票否决。

针对上面看到的问题,现在也有一些团队在尝试前后端之间加一个中间层(比如淘宝UED的 MidWay )。这个中间层由前端来控制。

JavaScript

+----------------+ | F2E | +---↑--------↑---+ | | +---↓--------↓---+ | Middle | +---↑--------↑---+ | | +---↓--------↓---+ | R2E | +----------------+

1
2
3
4
5
6
7
8
9
10
11
    +----------------+
    |       F2E      |
    +---↑--------↑---+
        |        |
    +---↓--------↓---+
    |     Middle     |
    +---↑--------↑---+
        |        |  
    +---↓--------↓---+
    |       R2E      |
    +----------------+

中间层的作用就是为了更好的控制数据的输出,如果用MVC模型去分析这个接口,R2E(后端)只负责 M(数据) 这部分,Middle(中间层)处理数据的呈现(包括 V 和 C)。淘宝UED有很多类似的文章,这里不赘述。

题目1: ajax 是什么?有什么作用?

ajax(Asynchronous JavaScript and XML 异步的JavaScript与XML技术),他利用HTML.CSS.Javascript.XML以及最最最重要的XMLHttpResponse接口向后端发送http请求实现不刷新页面的情况下更新部分页面内容.
步骤:
1.构建ajax, xhr = new XMLHttpResponse
2.设置发送方式.接口名字,参数. xhr.open('get','/loadMore?index='+pageIndex+'length=5',true)
3.设置header,文件格式等参数
4.发送HTTP请求,xhr.send()
5.接受数据,对数据进行操作
6.更新页面相关内容
作用:不刷新页面的情况下,更新部分页面内容,不耽误用户其他操作,提升用户体验.

三、小结

本文只是对前后端协作存在的问题和现有的几种常见模式做了简要的列举,JSON Schema 具体如何去运用,还有接口的维护问题、接口信息的获取问题没有具体阐述,这个后续有时间会整理下我对他的理解。

赞 2 收藏 1 评论

图片 1

题目4:实现加载更多的功能,效果范例338,后端在本地使用server-mock来模拟数据

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-6">
    <title>load-more</title>

    <style>
        a{
            text-decoration: none;
        }
        .ct {
            margin: 0;
            padding: 0;
            vertical-align: middle;
            text-align: center;
        }
        .ct li{
            list-style: none;
            border: 1px solid red;
            padding: 10px;
            margin: 10px 20px;
            color: blue;
            cursor: pointer;
            border-radius: 4px;
        }
        .ct li:hover {
            background-color: green;
            color: azure;
        }
        .btn-ct {
            text-align: center;
        }
        .btn {
            display: inline-block;
            margin: 20px auto;
            padding: 10px;
            background: yellowgreen;
            font-size: 18px;
            color: red;
            border-radius: 5px;

        }
        .btn:hover {
            background-color: deepskyblue;
            color: firebrick;
        }
    </style>
</head>
<body>
    <ul class="ct">
        <li>新闻0</li>
    </ul>
    <div class="btn-ct"><a  href="##" class="btn">加载更多</a></div>
</body>
<script>
    var ct = document.querySelector('.ct')
    var btn = document.querySelector('.btn')
    var pageIndex = 1
    var dataArrive = true//状态锁,防止重复点击
    function loadMore(){
        if(dataArrive === false){//用来判断是否为重复无效点击
            return
        }
        dataArrive = false
        var xhr = new XMLHttpRequest()
        xhr.onreadystatechange = function(){
            if (xhr.readyState === 4){
                if (xhr.status === 200 || xhr.status === 304){
                    console.log(xhr.responseText)
                    var results = JSON.parse(xhr.responseText)
                    console.log(results.length)
                    var fragment = document.createDocumentFragment()
                    for(var i = 0;i < results.length; i++){
                        console.log(i)
                        var node = document.createElement('li')
                        node.innerText = results[i]
                        fragment.appendChild(node)
                        pageIndex += 1;
                    }
                    ct.appendChild(fragment)
                }else{
                    console.log('error')
                }
                dataArrive = true
            }
        }
        xhr.open('get','/loadMore?index='+pageIndex+'&length=5',true)
        xhr.send()
    }
    btn.addEventListener('click',loadMore)
</script>
</html>

// 服务端 router.js


app.get('/loadMore', function(req, res) {

  var curIdx = req.query.index
  var len = req.query.length
  var data = []

  for(var i = 0; i < len; i++) {
    data.push('新闻' + (parseInt(curIdx) + i))
  }

  setTimeout(function(){
    res.send(data);
  },3000)

});
上一篇:浅谈html5 video 移动端填坑记,浅谈html5 下一篇:没有了