云开发 HTTP处理

2020-07-21 17:54 更新

在小程序端我们可以使用wx.request来与第三方api服务进行数据交互,那云函数除了可以直接给小程序端提供数据以外,能不能从第三方服务器获取数据呢?答案是肯定的,而且在云函数中使用HTTP请求访问第三方服务可以不受域名限制,即不需要像小程序端一样,要将域名添加到request合法域名里;也不受http和https的限制,没有域名只有IP都是可以的,所以云函数可以应用的场景非常多,即能方便的调用第三方服务,也能够充当一个功能复杂的完整应用的后端。不过需要注意的是,云函数是部署在云端,有些局域网等终端通信的业务只能在小程序里进行。

node流行的HTTP库比较多,比如got、superagent、request、axios、request-promise、fech等等,推荐大家使用axios,axios是一个基于promise的HTTP库,可以使用在浏览器和Nodejs环境中,下面也会以axios为例。

一、get请求

使用开发者工具,创建一个云函数,如axios,然后在package.json增加axios最新版latest的依赖并用npm install安装:

  1. "dependencies": {
  2. "wx-server-sdk":"latest",
  3. "axios": "latest"
  4. }

然后在index.js里输入以下代码,在前面章节里,我们在小程序端调用过知乎日报的API,下面还以知乎日报的API为例:

  1. const cloud = require('wx-server-sdk')
  2. cloud.init({
  3. env: cloud.DYNAMIC_CURRENT_ENV,
  4. })
  5. const axios = require('axios')
  6. exports.main = async (event, context) => {
  7. const url = "https://news-at.zhihu.com/api/4/news/latest"
  8. try {
  9. const res = await axios.get(url)
  10. //const util = require('util')
  11. //console.log(util.inspect(res,{depth:null}))
  12. return res.data;
  13. } catch (e) {
  14. console.error(e);
  15. }
  16. }

在小程序端调用这个云函数,就能返回从知乎日报里获取到的最新文章和热门文章,云函数端获取知乎日报的数据就不需要添加域名校验,比小程序端的wx.request方便省事很多。

注意,在上面的案例中,我们返回的不是整个res(response对象),而是response对象里的data。直接返回整个res对象,会报Converting circular structure to JSON的错误,如果你想返回整个res,可以取消上面代码里面的注释。Node的util.inspect(object,[showHidden],[depth],[colors])是一个将任意对象转换为字符串的方法,通常用于调试和错误输出。

上面的知乎链接本来就是API,返回的是json格式的数据,所以可以直接使用axios.get(),axios还可以用于爬虫,爬取网页,比如下面的代码就是爬取百度首页,并返回首页里的<title></title>里的内容(也就是网页的标题):

  1. const cloud = require('wx-server-sdk')
  2. cloud.init({
  3. env: cloud.DYNAMIC_CURRENT_ENV,
  4. })
  5. const axios = require('axios')
  6. exports.main = async (event, context) => {
  7. try {
  8. const res = await axios.get("https://baidu.com")
  9. const htmlString = res.data
  10. return htmlString.match(/<title[^>]*>([^<]+)<\/title>/)[1]
  11. } catch (e) {
  12. console.error(e);
  13. }
  14. }

如果想使用云函数做爬虫后台,抓取网页数据,可以使用cheerio和puppeteer等第三方开源依赖,这里就不多做介绍了。

二、post请求

结合前面在网络API里讲过的聚合数据历史上的今天API,我们也可以在云函数端发起post请求:

  1. const now = new Date(); //在云函数字符串时间时,注意要修改云函数的时区,方法在云函数实用工具库里有详细介绍
  2. const month = now.getMonth()+1 //月份需要+1
  3. const day = now.getDate()
  4. const key = "" //你的聚合KEY
  5. const url ="http://api.juheapi.com/japi/toh"
  6. const cloud = require('wx-server-sdk')
  7. cloud.init({
  8. env: cloud.DYNAMIC_CURRENT_ENV,
  9. })
  10. const axios = require('axios')
  11. exports.main = async (event, context) => {
  12. try {
  13. const res = await axios.post(url,{
  14. key:key,
  15. v:1.0,
  16. month:month,
  17. day:day
  18. })
  19. // const res = await axios.post(`url?key=${key}&v=1.0&month=${month}&day=${day}`)
  20. return res
  21. } catch (e) {
  22. console.error(e);
  23. }
  24. }

三、使用axios下载文件

要使用axios下载文件,需要将axios的responseType由默认的json修改为stream,然后将下载好的文件上传到云存储里,也可以将下载好的文件写入到云函数临时的tmp文件夹里,用于更加复杂的操作。

  1. const cloud = require('wx-server-sdk')
  2. cloud.init({
  3. env: cloud.DYNAMIC_CURRENT_ENV,
  4. })
  5. const axios = require('axios')
  6. //const fs = require('fs');
  7. exports.main = async (event, context) => {
  8. try {
  9. const url = 'https://tcb-1251009918.cos.ap-guangzhou.myqcloud.com/weapp.jpg';
  10. const res = await axios.get(url,{
  11. responseType: 'stream'
  12. })
  13. const buffer = res.data
  14. //我们也还可以将下载好的图片保存在云函数的临时文件夹里
  15. // const fileStream = await fs.createReadStream('/tmp/axiosimg.jpg')
  16. return await cloud.uploadFile({
  17. cloudPath: 'axiosimg.jpg',
  18. fileContent: buffer,
  19. })
  20. } catch (e) {
  21. console.error(e);
  22. }
  23. }
以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号