变脸式应用 - 调用后端接口

调用后端接口是筋斗云框架提供的两大核心功能之一。

[任务]

继续hello页面的例子,要求每次进入页面时,不是固定的显示”hello, world”,而是需要根据服务端的返回内容来显示hello的内容,比如”hello, skys”或是”hello, jdcloud”。

我们先定义一个叫做”hello”的交互接口,由前端发起一个HTTP GET请求,比如:

http://myserver/myproject/api.php?ac=hello

如果调用成功,后端返回JSON格式的数据如下:

[0, "jdcloud"]

其中0是返回码,表示调用成功。如果调用失败,可返回:

[99, "对不起,服务器爆炸了"]

以上就是一个符合筋斗云接口规范的简单例子(称为业务查询协议-BQP),在成功调用时应返回[0, data],在调用失败时应返回[非0, 错误提示信息]

有了清晰的接口定义,前后端就可以并行开发了。
在前端,我们把页面稍作修改以动态显示hello的内容:

    <div class="bd">
        <p>Hello, <span id="what"></span></p>
    </div>

再写一段逻辑,每当进入页面时调用hello接口并显示内容,我们选择onBeforeShow回调来做这件事:

function initPageHello() 
{
    var jpage = $(this);
    jpage.on("pagebeforeshow", onBeforeShow);

    function onBeforeShow()
    {
        callSvr("hello", api_hello);
    }

    function api_hello(data)
    {
        jpage.find("#what").html(data);
    }
}

callSvr是框架提供的一个重要函数,它封装了ajax调用的细节,完整的函数原型为:

callSvr(ac, param?, fn?, postParam?, options?);

其中,ac是调用接口名,fn是回调函数,param和postParam分别是URL参数和POST参数。除ac外,其它参数均可省略。例如

callSvr("hello");
callSvr("hello", {id: 1}); // URL: hello?id=1
callSvr("hello", {id: 1}, api_hello); // function api_hello(data) {}
callSvr("hello", api_hello, {name: "hello"});

回调函数api_hello仅在成功时被调用,参数data是实际数据,即[0, data]中的data部分,不包括返回码0。
当调用失败时,框架会统一处理,显示错误信息,无须操心。

调用模拟接口

上面代码写好了,后端接口还没做好怎么测试?

筋斗云支持模拟接口返回数据。 在mockdata.js中,可以设置接口的模拟返回数据:

MUI.mockData = {
    ...
    "hello": [0, "jdcloud"]
}

此处还可以用函数做更复杂的基于参数的模拟,详见API文档,查询MUI.mockData

运行H5应用,进入hello页面,看看是不是可以正常显示了?

可以动态修改模拟数据,在控制台中输入:

MUI.mockData["hello"] = [0, "skys"]

然后从hello页返回首页,再进入hello页,看看显示内容是不是变了?

再改一个出错的试试:

MUI.mockData["hello"] = [99, "对不起,服务器爆炸了"]

进入hello页,我们看到,调用失败时,回调函数api_hello没有执行,而是框架自动接管过去,显示出错信息。

调用真实接口

在后端接口开发好后,我们可去掉对这个接口的模拟,直接远程调用服务端接口。这需要配置好后端接口的地址。

我们用php写一个简单的符合筋斗云接口规范的后端实现,通过名为”ac”的URL参数表示接口名,在server目录中创建文件api.php如下:

<?php

@$ac = $_GET['ac'];
if ($ac == 'hello') {
    $what = "jdcloud @ " . time();
    echo json_encode([0, $what]);
}
else {
    echo json_encode([1, "bad ac"]);
}

配置好php的调用环境后,访问

http://localhost/myproject/api.php?ac=hello

输出类似这样(根据时间动态变化):

[0,"jdcloud @ 1483526151"]

回到前端,我们在app.js中设置服务端接口地址:

    $.extend(MUI.options, {
        serverUrl: "api.php",
        serverUrlAc: "ac"
    });

serverUrl选项设置了服务端的URL地址,因为我们将”api.php”放在与”index.html”同一目录下,所以直接用相对路径就可以了。serverUrlAc选项定义了接口名对应的URL参数名称,即?ac={接口名}.
在mockdata.js中去掉对”hello”接口的模拟,刷新应用就可以看到调用后端的效果了。

如果前后端不在同一台服务器上,则要将URL写完整,如

serverUrl: "http://myserver/myproject/api.php";

注意:后端应设置好允许跨域请求。这里不做详述。

以上讲述的是符合筋斗云接口规范的接口调用设置,如果不符合该规范,请阅读下一节“接口适配”。

接口适配

在上例中,假定了后端接口兼容筋斗云接口规范,例如返回格式为[0, jsonData][非0, 错误信息]
如果接口协议不兼容,则需要做接口适配。

接口适配的目标是通过callSvr函数更加简练地调用后台接口,同时达到:

  • 调用出错统一处理,例如未认证错跳转到登录页,其它错误弹出错误提示框等。
  • 写代码时只需要处理调用成功后返回的数据,不用每次调用都处理各种错误。

[任务]

适配以下接口协议规范,约定接口返回格式为:{code, msg, data}
例如上例中的hello接口,调用成功时返回:

{
    "code":"0",
    "msg":"success",
    "data":"jdcloud"
}

失败返回:

{
    "code":"99",
    "msg":"对不起,服务器爆炸了"
}

这时需要对callSvr进行适配,可以在app.js中,设置 MUI.callSvrExt如下:

    MUI.callSvrExt['default'] = {
        makeUrl: function(ac) {
            return 'http://hostname/lcapi/' + ac;
        },
        dataFilter: function (data) {
            if ($.isPlainObject(data) && data.code !== undefined) {
                if (data.code == 0)
                    return data.data;
                if (this.noex)
                    return false;
                app_alert("操作失败:" + data.msg, "e");
            }
            else {
                app_alert("服务器通讯协议异常!", "e"); // 格式不对
            }
        }
    };

我们在mockdata.js中设置好模拟数据用于测试:

MUI.mockData = {
    "User.get": {code: 0, msg: "success", data: user},
    "hello": {code: 0, msg: "success", data:"myworld"}
    ...
}

上例中,User.get接口在显示首页是会调用,所以和”hello”接口一并模拟下。

测试接口调用:

callSvr("hello", console.log);
或
callSvrSync("hello");

callSvrSynccallSvr的同步调用版本,它直接等到调用完成才返回,且返回值就是调用成功返回的数据。

可以动态修改模拟数据:

MUI.mockData["hello"] = {code: 99, msg: "对不起,服务器爆炸了"}

在接口适配完成后,应用层代码不用去做任何修改。
进入页面看看,是不是和上节的运行结果是一样的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值