API调用是开发者在小程序开发过程中经常遇到的问题,本期我们将以豆瓣电影API的调用为例,来看看API调用的流程以及一些常见问题。
测试使用的小程序为“电影周刊”,内容来自清华大学软件学院刘强副教授在“学堂X”开设的小程序开发系列课程。
豆瓣API简单介绍
为了简化课程讲解,我们将采用直接调用的方式,没有使用到任何认证,也没有对应的申请和使用,所以这种调用方式会受到严格限制。
我们以调用豆瓣电影条目信息API为例,该API可以获取电影详情,具体怎么调用呢?
我们先来看一下。
URI:/v2///:id,
这个目录下有一个冒号id,这是一个API的设计方式,就是把你想要指定的目标影片的id直接包含在URI路径里,而不是通过.
我们通过浏览器试试这个API调用的结果,首先输入豆瓣API的域名,然后连接API路径,最后添加目标电影的id,这里我们指定电影《教父》的id值。
这样的http请求返回的原始数据是一个json对象格式的文本,在它的json对象格式中返回了很多对应的字段信息,比如电影的各种评分,wish字段体现了有多少人想看这个电影,字段给出了三种不同大小的电影海报图片URL,字段给出了电影的标题等等。
403 问题
在之前的逻辑中,每次打开页面时,可以从初始化的时候的参数对象中获取需要展示的目标影片的id,然后需要调用豆瓣的入口信息API传递这个id,API就会返回这个id对应的影片详情数据。
我们之前看到过,完整的 URL 如下所示。
目标影片的id直接通过URL路径的一部分传递过来,因此这里我们不需要定义data属性,因为没有额外的数据,我们也不定义属性,参数默认使用GET方法,所以就不指定了。
这里指定了一个回调函数,我们看看它接收了什么对象,然后执行调用,结果却是403。
从返回的结果中我们可以看到《教父》这部电影对应的id值是99,前面我们了解了《教父》这部电影的id值是。替换掉正确的id之后,我们再次调用。
这次我们得到了正确的URL,和刚才我们直接通过浏览器访问商品信息API时的URL是一样的。
直接通过浏览器访问可以正确获取到对应的json对象文本,但是通过小程序方法调用API却返回403,请问是什么原因呢?
因为今年年初,小程序直接调用和公众调用太多,所以豆瓣禁止了小程序直接调用。
你可能会问,豆瓣怎么判断对它的调用请求是来自小程序的呢?
小程序在每次请求中都会设置固定的字段,豆瓣收到请求后,如果发现该值是小程序框架固定的格式,则会直接返回403。
那么我们在调用的时候,是否可以通过定义参数来修改相应的值呢?小程序框架也是禁止了的设置,也就是说我们在调用的时候,参数中的设置也是无效的。
从这点我们也可以看出小程序对它的每一个http请求都打上了自己的固定标记,那么我们如何解决这个问题呢?
我们可以通过一个中间服务器来重置,具体来说,可以在小程序和豆瓣API之间设置相应的转发代理来实现。
我们在转发代理中做一个页面,把收到的值改成随机值,转发代理收到小程序发送的请求后,会抹掉小程序中的固定标记,然后发送给豆瓣,豆瓣会把这个请求当成正常请求来处理,这样就能正常返回相应的明细数据了。
因为小程序请求的每个服务器域名都要先去ICP备案后才能在后台配置使用,课程中我们没来得及去注册自己的域名,所以直接使用了豆瓣API的第三方转发代理。
我们将请求从直接发送到豆瓣改为先发送到转发代理。
运行之后我们发现,这次收到了400 bad ,如何解决这个问题呢?
为了解决这个问题,我们必须在请求的时候为http请求设置一个特定的类型值。
当我们将该值设置为json之后,本次方法调用没有抛出任何错误,在回调函数处理的时候显示了200 OK。
并且在data属性中我们成功保存了本次API调用返回的目标影片详情数据对应的json文本对象转换而来的一个对象,这个对象其实是对此目标影片各类详情数据的封装。
在接收到返回的目标影片详情数据之后,我们可以将其保存为页面的内部状态数据。
我们先通过方法的this指针,把这个页面的page对象的引用保存下来,保存到一个that变量中,然后在回调函数处理的时候,直接通过that变量获取外部的page对象的引用,然后在其中访问该方法。
调用完之后我们通过type检查,最终找到页面中命名的内部变量,这个变量里面包含了这部电影对应的各种详细数据。
页面详细展示
接下来我们将接收到的详情数据进行渲染输出到视图地图中进行展示,具体的展示方式是通过新增加的内部状态变量绑定影片详情对象中的相关属性。
我们通过数据绑定,将接收到的影片详情对象中的属性、愿望属性、属性等渲染并输出到相应元素上进行显示。
我们还可以设置元素的高度和宽度来进行简单的样式优化。
这时候我们再看看页面上的另外两部电影,点击之后都返回了404 Not。这是因为这两部电影的id并不是真正的豆瓣id,所以豆瓣电影返回了404响应。
其实这时候我们还是进入了回调函数处理,还是将接收到的data属性的值保存到了内部的状态变量中,所以此时的值虽然保存了这样的一个对象,但是它并不是一个普通的影片详情数据对象,在这个对象中是找不到我们需要的各种字段数据。
所以一般处理的时候,我们需要单独判断,只把返回正常的数据保存到内部状态变量中,我们来判断一下是否是200 OK。
此时我们还没有在页面中添加这样的内部状态变量,只有当可以找到影片并且返回200 OK时,才可以添加相应的内部状态变量。
我们将另外两部电影的id改为正确的值,然后点击每部电影,其对豆瓣的调用就可以正常使用了。