JSRUN 用代码说话

网络 API

编辑教程

网络 API

数据和文件是小程序开发非常重要的元素,在前面的章节里,数据和文件等的存储都是在小程序的页面进行渲染、或是页面间传递或与本地手机交互。这一节我们会来介绍数据、文件如何与网络HTTP进行数据、文件的对话,如何获取并上传网络数据和文件。

数据API

小程序以及很多程序的API是预先就已经写好的函数,使我们不需要对底层有太多了解,只需要按照技术文档进行传递参数就能调用出非常复杂的功能。而还有一类API则侧重于把数据资源给开放出来,我们可以通过HTTP的方式来使用这些数据。

了解网络数据API

复制以下链接地址,用浏览器打开,看看会返回什么结果:

//知乎日报的最新话题
https://news-at.zhihu.com/api/4/news/latest
//知乎日报某一个话题的内容
https://news-at.zhihu.com/api/4/news/9714883
//v2ex论坛的最新主题
https://www.v2ex.com/api/topics/latest.json
//CNode论坛的最新话题
https://cnodejs.org/api/v1/topics

以上所返回的数据类型都是json格式,相信大家应该比较熟悉了。那我们如何把以上数据渲染到我们的小程序页面上呢?

数据是一种资源,比如新闻资讯、电商商品、公众号文章、股市行情、空气质量和天气、地图、词典翻译、快递信息、书籍信息、音乐视频、财务公司信息等等这些都是数据,数据也是一种商品,一种服务,通常它的使用对象是开发者,有些免费,有些也会收取一定的费用,大家可以通过综合性API服务平台聚合API来对API服务有一个基础的了解。

练手API资源推荐

这里推荐几个程序员经常会拿来练手的API资源,你可以使用这些API来做网站、小程序、移动端(iOS、安卓)、桌面端,也可以用于各种框架比如Vue、React、Flutter等等,数据没变,只是解决方案不同。

聚合API 一个比较全面的综合性API服务平台
即速API 也是提供一些综合性的API服务
V2EX API v2ex论坛是很多程序员经常会光顾的综合性技术论坛
CNode API Nodejs交流论坛
和风天气 含天气预报、空气质量、实况天气等数据
Github API Github是所有程序员都(必须)会使用的网站
知乎日报API 知乎日报API分析

各大公司的开发平台:比如微信开放平台提供了微信账号体系的接入,腾讯云API中心则提供了调用云资源的能力(包含服务器、物联网、人工智能等API)、开源网站Wordpress也提供API调用的服务,在API资源的开放方面,国外也做得比较领先(国外免费API列表)。而对于特定的数据资源,也可以通过爬虫等方式来自建。

渲染网络数据到页面

要渲染从API里获取到的数据,首先我们需要对API里的字段(属性)到底是干什么的要有一定的了解。比如知乎日报的API字段如下,这个可以从API相关的文档里了解到以及需要我们结合Console.log来对比了解。

比如date : 日期;stories : 当日新闻;title : 新闻标题;images : 图像地址;id : url 与 share_url 中最后的数字为内容的 id;top_stories : 界面顶部轮播的显示内容,这些在做数据渲染前就需要有所了解。

获取网络数据

使用开发者工具新建一个request页面,然后在request.js里的onLoad生命周期函数里输入以下代码:

  onLoad: function (options) {
    wx.request({
      url: 'https://news-at.zhihu.com/api/4/news/latest', //知乎日报最新话题
      header: {
        'content-type': 'application/json' // 默认值
      },
      success(res) {
        console.log('网络请求成功之后获取到的数据',res)
        console.log('知乎日报最新话题',res.data)
      }
    })
  },

域名校验与白名单

编译之后,在控制台Console你会看到如下报错,你的域名不在域名白名单里面,这是因为小程序只可以跟指定的域名与进行网络通信。

request:fail url not in domain list

解决方法有两种,一是打开开发者工具工具栏右上角的详情,勾选不校验合法域名、业务域名、TLS版本以及HTTPS证书;二是你可以去小程序的管理后台(注册小程序时的页面),点击开发–开发设置,在request合法域名处添加该域名(如果你不想把这个小程序发布上线,没有必要添加)。

res对象和res.data对象

编译之后,在控制台Console就可以看到打印的res对象,以及res里的data对象。res.data的数据正是我们使用浏览器打开链接所得到的json数据,结合我们之前学到的数据渲染方面的知识,相信大家应该对如何将数据渲染到页面就不会感到陌生了。

在打印的res对象有一些参数,比如cookies、header、statusCode这些是什么意思呢?我们可以来结合技术文档深入了解。

statusCode:开发者服务器返回的 HTTP 状态码,也就是指示HTTP请求是否成功,其中200为请求成功,404请求失败,更多状态码的知识可以查阅MDN HTTP响应代码
header:开发者服务器返回的 HTTP消息头,其中Content-Type为服务器文档的MIME 类型,API的MIME类型通常为 "application/json; charset=UTF-8",建议服务器返回值使用 UTF-8 编码(如果你有服务器的话)。
wx.request只能发起 HTTPS 请求,默认超时时间为60s,最大并发限制为10个

小任务:把request的链接换成v2ex、cnode论坛的API链接以及知乎日报某一个话题的内容API,看看是什么结果?你知道返回来的json数据的每一条属性代表的意思吗?

将数据渲染到页面

既然我们已经从知乎日报的API取得了数据,那渲染数据的方法以及如何实现跨页面渲染,在前面的章节我们已经就有所了解了。

简单的知乎日报首页

使用开发者工具在request.wxml里输入weui的列表样式(需要引入weui框架哦)

<view class="page__bd">
    <view class="weui-panel weui-panel_access">
        <view class="weui-panel__bd" wx:for="{{stories}}" wx:for-item="stories" wx:key="*item">
            <navigator url="" class="weui-media-box weui-media-box_appmsg" hover-class="weui-cell_active">
                <view class="weui-media-box__hd weui-media-box__hd_in-appmsg">
                    <image class="weui-media-box__thumb" mode="widthFix" src="{{stories.images[0]}}" sytle="height:auto"></image>
                </view>
                <view class="weui-media-box__bd weui-media-box__bd_in-appmsg">
                    <view class="weui-media-box__title">{{stories.title}}</view>
                </view>
            </navigator>
        </view>
    </view>
</view>

然后再在request.js的data里声明date、stories、top_stories的初始值(使用的变量和API的字段尽量保持一致,这样就不容易混乱)

  data: {
    date:"",
    stories:[],
    top_stories:[],
  },

在onLoad生命周期函数里将数据通过setData的方式给赋值给data:

  onLoad: function (options) {
    let that=this
    wx.request({
      url: 'https://news-at.zhihu.com/api/4/news/latest', 
      header: {
        'content-type': 'application/json' 
      },
      success(res) {
        let date=res.data.date
        let stories=res.data.stories
        let top_stories = res.data.top_stories
        that.setData({
          date,stories,top_stories
        })
      }
    })
  },

编译之后,我们就能看到知乎日报的数据就渲染在页面上了。

小任务: top_stories 是界面顶部轮播的显示内容,制作一个swiper轮播,将top_stories里的内容渲染到轮播上。

打开开发者工具调试工具栏的AppData标签页,就能看到从网络API里获取到的数据。也可以在此处编辑数据,并及时地反馈到界面上。如果AppData里有数据,可以确认页面已经取得res里的data数据,如果数据没有渲染到页面,说明列表渲染可能有误。通过这种方式可以诊断页面渲染问题所在。

详情页数据渲染

前面我们获取的只是知乎的最新文章列表,那文章里面的内容呢?通过API文档以及我们通过链接访问的结果来看,我们只需要取得了文章的ID,就能从API里获取到文章的详情页内容:

https://news-at.zhihu.com/api/4/news/9714883  //9714883是文章的ID

使用开发者工具新建一个story页面,然后在story.wxml里输入以下代码:

<view class="page__bd">
    <view class="weui-article">
        <view class="weui-article__h1">{{title}}</view>
        <view class="weui-article__section">
            <view class="weui-article__section">
                <view class="weui-article__p">
                    <image class="weui-article__img" src="{{image}}" mode="widthFix" style="width:100%" />
                 </view>
                 <view class="weui-article__p">                      
                      {{body}}                
                </view>
                <view class="weui-article__p">
                        知乎链接:{{share_url}}
                </view>
            </view> 
        </view>     
    </view>   
</view>

然后再在request.js的data里声明title、body、image、share_url的初始值:

data: {
    title:"",
    body:"",
    image:"",
    share_url:"",
  },

在onLoad生命周期函数里调用wx.request获取文章详情页的数据,并通过setData的方式给赋值给data:

  onLoad: function (options) {
    let stories_id=9714883
    let that = this
    wx.request({
      url: 'https://news-at.zhihu.com/api/4/news/'+stories_id,
      header: {
        'content-type': 'application/json'
      },
      success(res) {
        let title = res.data.title
        let body=res.data.body
        let image=res.data.image
        let share_url=res.data.share_url
        that.setData({
          title,body,image,share_url
        })
      }
    })

编译之后,发现数据虽然渲染出来了,但是存在“乱码”(是HTML标签),那这个要如何处理呢?这个就涉及到小程序的富文本解析了。

HTML标签解析rich-text

只需要将富文本对象放在rich-text的nodes里,就能将富文本解析出来了,比如将上面的{{body}}替换成以下代码。

<rich-text nodes="{{body}}"></rich-text>

小程序富文本解析的方案还有:Comi ,腾讯 Omi 团队开发的小程序代码高亮和 markdown 渲染组件,Github地址,具体效果可以在微信小程序里搜索omiCloud;以及wxPrase,微信小程序富文本解析自定义组件,支持HTML及markdown解析,Github地址,当你遇到更加复杂的富文本解析时,可以来深入了解。

跨页面数据渲染

上面我们只是渲染了单篇文章的详情页,那如何点击文章列表就能渲染与之相应的文章详情页呢?这就回到了我们之前学过的跨页面数据渲染。

首先把request页面置于首页,然后再给request.wxml里的navigator组件的链接上携带文章的id:

url="/pages/story/story?id={{stories.id}}"

当点击request页面的链接时,链接携带的数据就会传到story页面的生命周期函数onLoad的options对象里,将options里的id,赋值给stories_id,也就是将文章id 9714883修改为options.id

let stories_id=options.id

这样再来点击request页面的链接,不同的链接就会渲染不同的文章详情。

解构赋值

解构赋值也就是从数组Array和对象Object中提取值,按照对照的位置,对变量进行赋值。比如上面的变量声明,为了能够与API里的数据字段一一对应,我们会声明很多变量,知乎日报的API还算比较少的,多了就比较复杂了。

let title = res.data.title
let body=res.data.body
let image=res.data.image
let share_url=res.data.share_url

这时可以简写成:

let { title, body, image, share_url}=res.data

历史上的今天

知乎日报的API是比较开放的,并不需要我们去注册API服务就能获取到这些数据,但是大多数情况下,API是商品服务,需要我们注册,那需要注册的API和开放的API有什么不同呢?

注册历史上的今天的服务

注册聚合API并认证,认证之后可以申请开通历史上的今天、图书电商数据等免费的API服务,并找到你的与之对应的AppKey。

替换下面链接你的历史上的今天对应的key(直接输AppKey就行),然后在浏览器打开链接(下面这个是1.0版)

http://api.juheapi.com/japi/toh?month=9&day=15&key=你的历史上的今天对应的key 也可以选择事件列表的2.0版(为了讲解方便,下面以1.0版本为主)

http://v.juhe.cn/todayOnhistory/queryEvent.php?date=9/15&key=你的历史上的今天对应的key key的存放 通常我们会把拿到的key放在app.js的globalData里,或者在小程序里新建一个config.js,方便以后全局调用,而不是把key直接写在页面里。

方法一:写在app.js里的globalData,或者新建一个keyData对象,只要达到全局调用的目的都可以,以globalData为例

  globalData: {
    juheKey:"366444.......00ff", //聚合AppKey
  },

这种方式调用时首先在页面的js文件里、Page()函数的前面使用

const app=getApp()

之后就可以使用app.globalData.juheKey来调用它了。

方法二:也可以在小程序的根目录或者utils文件夹新建一个config.js,然后结合前面模块化的知识,写入以下代码:

module.exports = {
  juheKey:"366444.......00ff", //聚合AppKey
}

这种方式调用时我们需要先在页面的Page()函数前面引入模块化文件

const key = require('../../utils/config.js')

然后就可以使用key.juheKey调用它了。

将一些通用的数据、函数单独拿出来存放在globalData里或进行模块化,是在实际开发中会经常使用到的一种方法,它可以让数据、函数更容易管理以及可以重复利用,使得代码更加精简。

wx.request请求数据

使用开发者工具新建一个apidata页面,然后在apidata.js的Page()函数前面输入以下代码:

const app=getApp()
const now = new Date(); 
const month = now.getMonth()+1 //月份需要+1
const day = now.getDate()

然后再在生命周期函数onLoad里输入wx.request数据请求:

  onLoad: function (options) {
    wx.request({
      url: 'http://api.juheapi.com/japi/toh', 
      data: {
        month: month,
        day: day,
        key: app.globalData.juheKey,
      },
      header: {
        'content-type': 'application/json'
      },
      success(res) {
        console.log(res.data)
      }
    })
  },

wx.request里的data就是要传入的参数,我们把month、day、key传入到请求的链接里。它等价于以下链接(注意把data里的属性值,以免传两次参数)

url: "http://api.juheapi.com/japi/toh?" + "month=" + month + "&day=" + day + "&key=" + app.globalData.juheKey,

模板字符串

要将多个字符串连接起来,可以使用加号+来用作字符串的拼接,如果变量比较多,是不是很麻烦?我们还可以使用模板字符串,模板字符串使用反引号 ``来表示(在电脑键盘esc按键下面)。要在模板字符串中嵌入变量,需要将变量名写在 ${}之中,比如上面的链接也可以写成:

url: `http://api.juheapi.com/japi/toh?month=${month}&day=${day}&key=${app.globalData.juheKey}`,

在控制台我们就可以看到获取到的res.data数据,至于如何渲染到页面,这里就不多介绍了。

天气API

注册和风天气,并在控制台的应用管理新建一个应用,获取到该应用的key,按照上面的方法将key添加到globalData里:

  globalData: {
    heweatherKey:"732c.........0b", //和风天气key
  }

通过技术文档我们可以了解到免费版和风天气API的必备字段为weather-type(根据不同的值可以取得不同的数据)和请求参数(其中location为必备参数)

也就是我们可以通过链接可以获取到数据,注意now在问号?的前面,也就是它不是请求的参数,location和key才是。

https://free-api.heweather.net/s6/weather/now?location=beijing&key=你的key

然后再在apidata.js Page()的data里初始化声明weathertype(属性名最好不要有连接符-)和location:

  data: {
    weathertype:"now",
    location:"beijing"  //location的写法有很多种,具体可以参考技术文档
  },

然后再在生命周期函数里添加wx.request请求(onLoad里可以写多个wx.request请求)

    const weathertype=this.data.weathertype
    wx.request({
      url: `https://free-api.heweather.net/s6/weather/${weathertype}`,
      data: {
        location: that.data.location,
        key: app.globalData.heweatherKey,
      },
      header: {
        'content-type': 'application/json'
      },
      success(res) {
        console.log(res.data)
      }
    })
  },

在控制台就能看到请求到的res.data了。如果你想点击按钮切换不同城市以及不同的天气数据类型,结合前面所学的知识,我们只需要通过事件处理函数调用setData修改weathertype和location即可。

encodeURI与decodeURI

在浏览网页的时候我们经常看到汉字或一些字符变成了一个“乱码”,原因就在于链接进行了编码处理。encodeURI() 函数可把字符串作为 URI 进行编码,而decodeURI()函数则可以进行解码。

在开发者工具的控制台里输入以下代码

console.log(encodeURI("北京"))
console.log(decodeURI("%e9%85%92%e5%ba%97"))
console.log(decodeURI("https://hackwork.org/handbook/python/174/%e5%86%99%e5%87%ba%e7%ac%ac%e4%b8%80%e8%a1%8cpython%e4%bb%a3%e7%a0%81/"))

腾讯地图LBS

如果想在小程序中调用地图的POI检索(POI,即兴趣点Point of Interest,区域内搜索酒店、学校、ATM等)、 关键词输入提示、地址解析、逆地址解析、行政区划、距离计算、路径规划等数据服务,这时候就需要使用到地图类相关的API。

注册账号获取Key

首先在注册后登录,点击控制台 —key管理—创建新密钥,然后取得key,key的格式类似于“43UBZ-----HTBIA”。

然后点击当前Key的设置,启动产品里勾选微信小程序和WebServiceAPI里的签名校验,获取到地图的Secret key。这两种API的调用方式,小程序都支持。

然后将地图的两个key,写入到globalData里

  globalData: {
    mapKey:"43UBZ-*****-IITUH-*****-2M723-******",//你的key
    mapSecretKey:"spZwWz**********Xh20uW", //你的Secret key
  }

md5加密算法

在WebServiceAPI Key配置中签名校验里提到我们使用WebServiceAPI的方法需要对请求路径+”?”+请求参数+SK进行拼接,并计算拼接后字符串md5值,即为签名(sig)。MD5是计算机安全领域广泛使用到的一种加密算法,主要用于确保消息传输的完整一致。

解压之后,将js文件夹里的md5.min.js复制粘贴到小程序utils文件夹下。然后再在Page()前面引入这个文件

const md5 = require('../../utils/md5.min.js')

坐标逆解析

坐标的逆解析就是坐标(latitude,longitude)转化为详细的地址名。

再在apidata.js Page()的data里初始化声明latitude,longitude,比如我们用腾讯大厦的经纬度值:

  data: {
    latitude:"22.540503",
    longitude: "113.934528",
  },

然后在onLoad函数里调用wx.request发起HTTPS网络请求

  onLoad: function (options) {
   let that=this
    const { latitude, longitude } = that.data
    const { mapKey, mapSecretKey}=app.globalData
    let SIG = md5("/ws/geocoder/v1?key=" + mapKey + "&location=" + latitude + "," + longitude + mapSecretKey)
    wx.request({
      url: 'https://apis.map.qq.com/ws/geocoder/v1',
      data: {
        key: mapKey,
        location: `${latitude},${longitude}`,
        sig: SIG
      },
      header: {
        'content-type': 'application/json'
      },
      success(res) {
        console.log(res.data)
      }
    })   
  },

在控制台Console就可以看到当前坐标(latitude,longitude)逆解析出来的详细信息。

JSRUN闪电教程系统是国内最先开创的教程维护系统, 所有工程师都可以参与共同维护的闪电教程,让知识的积累变得统一完整、自成体系。 大家可以一起参与进共编,让零散的知识点帮助更多的人。
X
支付宝
9.99
无法付款,请点击这里
金额: 0
备注:
转账时请填写正确的金额和备注信息,到账由人工处理,可能需要较长时间
如有疑问请联系QQ:565830900
正在生成二维码, 此过程可能需要15秒钟