小程序·云开发的HTTP API调用丨实战

小程序云开发之httpApi调用。

小程序云开发之httpApi调用(返回“47001处理”)

技术栈

采用 nodejs + express 搭建web服务器,采用 axios 请求第三方 httpApi

nodejs
express
axios

项目结构

通过应用生成器工具 express-generator 可以快速创建一个应用的骨架。

主要的核心文件 routes/base.js(api设置),util/rq.js(axios封装),views/base.pug(接口文档)


|---bin (框架生成,服务启动命令文件夹)
|---public (框架生成,静态资源存储)
|-------images
|-------javascripts
|-------stylesheets
|---routes (框架生成,路由配置/api)
|-------base.js // base相关接口及文档说明页
|---util (自行添加文件夹,放置公用js)
|-------result.js // 最终返回结果包装js
|-------rq.js // axios封装
|---views (框架生成,页面存放)
|-------error.pug
|-------base.pug (自行添加pug模板页面,用于base接口说明)
|-------index.pug
|-------layout.pug
|---app.js (框架生成,项目核心)
  • axios封装(util/rq.js)

// 模块引用
let axios = require("axios")
let qs = require("qs")

// 变量声明
const CONFKEY = "dev"
const BASECONF = {
    "dev":{
        baseUrl:'https://api.weixin.qq.com/',
    },
    "prod":{
        baseUrl:'https://api.weixin.qq.com/'
    }
}[CONFKEY]

// 创建rq请求并设置基础信息
const rq = axios.create({
    baseURL: BASECONF.baseUrl,
    timeout: 10000,
    headers: { // 请求头设置,(微信云开发数据APi采用application/json格式入参,否则导致47001错误)
        "Content-Type":"application/json; charset=utf-8"
    }
})

// axios 请求头拦截器
rq.interceptors.request.use(req => {
    // 有需要的,在此处拦截请求入参进行处理
    return req
},error => {
    return Promise.reject(error)
})

// axios 返回信息拦截器
rq.interceptors.response.use(res => {
    return res.data
},error => {
    return Promise.reject(error)
})

const $rq = { // 封装get,post请求

    get(url,params) { // axios.get(url,config)
        return rq.get(url,{
            params: params
        })
    },
    post(url,params={}) {
        return rq({ // axios(config)
            url: url,
            method: 'post',
            data:params
        })
    }
}

module.exports = {
    $rq
}
  • api设置 (routes/base.js)

var express = require('express');
var router = express.Router();
var { $rq } = require("../util/rq")
let result = require("../util/result.js")

/* GET base page. */
router.get('/', function(req, res, next) { // base pugApi说明文档
    res.render('base', { title: 'baseApi',
        apiList:[
            {
                url:"base/getAccessToken(请求第三方Api,获取access_token)",
                method:"GET",
                params:{
                    key:"grant_type",
                    appid:"小程序appid",
                    secret: "小程序密钥"
                },
                result:{
                    "success": true,
                    "data":`{
                        "access_token":"23_w0OtD1X72LIQo4dwctVsp99kjtIRRk9Gw5bx7UOglotfL7k9LqB1gKbZw86CNht6cnCv9oKBcFEcPg5u4seXN0hJMSEocsbun2dQxCTyZarP06YcToVbdP-MOLc7o7EhMSzqR4URT__BdZc-NMLbAIARQP",
                        "expires_in":7200
                    }`
                }
            },
            {
                url:"base/getdatabase(获取指定云环境集合信息)",
                method:"post",
                params:{
                    env:"云开发数据库环境id",
                    limit:"获取数量限制,默认10",
                    offset:"偏移量,默认0"
                },
                result:{
                    "success": true,
                    "data":`{
                        {
                        "errcode": 0,
                        "errmsg": "ok",
                        "collections": [
                            {
                                "name": "geo",
                                "count": 13,
                                "size": 2469,
                                "index_count": 1,
                                "index_size": 36864
                            },
                            {
                                "name": "test_collection",
                                "count": 1,
                                "size": 67,
                                "index_count": 1,
                                "index_size": 16384
                            }
                        ],
                        "pager": {
                            "Offset": 0,
                            "Limit": 10,
                            "Total": 2
                        }
                      }
                    }`
                }
            }
        ]
    });
});

router.get('/getAccessToken', function(req, res, next) { // 请求第三方Api,获取access_token
    let urlParam = { // appID,secret信息最好是不暴露在外故在此处直接写死即可
        grant_type:"client_credential",
        appid: "appid",
        secret: "secret"
    };
    $rq.get("cgi-bin/token",urlParam).then(response=>{
        global.TOKEN_INFO = response // global nodejs 全局对象,占用内存
        let r =  result.createResult(true, response); // 返回结果包装成固定格式
        res.json(r);
    }).catch(err=>{
        let r =  result.createResult(false, err);
        res.json(r);
        console.log(err)
    })
});

router.get('/getdatabase', function(req, res, next) { // 获取指定云环境集合信息
    let urlParam = { // 获取access_token之后才能调用其他接口,其他接口的入参就无需传入access_token因为皆须要拼接在接口后
        // access_token: req.query.access_token?req.query.access_token:"",
        env: req.query.env?req.query.env:"test-3b6a08",
        limit: req.query.limit?req.query.limit:10,
        offset: req.query.offset?req.query.offset:0
    };
    $rq.post("tcb/databasecollectionget?access_token="+global.TOKEN_INFO.access_token,urlParam).then(response=>{
        let r =  result.createResult(true, response);
        res.json(r);
    }).catch(err=>{
        let r =  result.createResult(false, err);
        res.json(r);
        // console.log(err)
    })
});

module.exports = router;
  • 配置app.js 使路由及接口生效(仅)

var createError = require('http-errors'); // 处理错误
var express = require('express');
var path = require('path'); // 路径
var cookieParser = require('cookie-parser'); // cookie
var logger = require('morgan'); // 日志
var sassMiddleware = require('node-sass-middleware'); // sass 中间件

var indexRouter = require('./routes/index'); // index 路由
var baseRouter = require('./routes/base') // base 路由

var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views')); // 设置视图根目录
app.set('view engine', 'pug'); // 使用 pug 模板

// 声明使用中间件
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(sassMiddleware({
  src: path.join(__dirname, 'public'),
  dest: path.join(__dirname, 'public'),
  indentedSyntax: true, // true = .sass and false = .scss
  sourceMap: true
}));
app.use(express.static(path.join(__dirname, 'public')));

app.all('/*',function (req, res, next) { // 解决跨越问题
  res.header('Access-Control-Allow-Origin', '*');
  res.header('Access-Control-Allow-Headers', 'Content-Type, Content-Length, Authorization, Accept, X-Requested-With');
  res.header('Access-Control-Allow-Methods', 'PUT, POST, GET, DELETE, OPTIONS');
  if (req.method == 'OPTIONS') {
    res.sendStatus(200);
  }
  else {
    next();
  }
});

// 声明路由
app.use('/', indexRouter);
app.use('/base', baseRouter);

// catch 404 and forward to error handler 自定义404中间件
app.use(function(req, res, next) {
  next(createError(404));
});

// error handler 自定义错误抛出中间件
app.use(function(err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.render('error');
});

module.exports = app;


至此,小程序云开发----httpApi调用已完成。

简单的利用vue+elementui做个云开发小程序后台管理页面调用下上面的接口

我们看下效果如下:

云开发小程序后台管理环境调整:

本地启动上面的接口服务及调用结果:

本地启动接口服务

本地接口调用结果

接口上传至服务器调用结果:



至此小程序云开发----httpApi调用完工。

过程中遇到的问题

  • 在post获取数据库集合信息时,第三方返回错误码“47001”
    在网上查了下,有很多遇到这个问题的。但如何解决说的大都不明不白,或者未解决,或者解决了帖子未更新。
  • 本人遇到该问题时,先是在官方社区搜索了相关提问,发现官方回复,在postman上尝试调用如果无恙请检查自身代码。
  • 依言自行在postMan上自行查验一波,发现我不论如何变更入参格式依然是“47001”的报错。此时我的入参如下:

     {
         access_token:"获取到的access_token",
         env: "云开发环境Id",
         limit: 10,
         offset: 0
     }
  • 多次查看对应httpApi文档,不断思索问题出在哪里。自身代码也没啥毛病啊,这是为啥呢?会不会是入参的问题呢?access_token已经在请求url上拼过一次是不是入参的时候就不需要了呢?入参的格式是什么呢?post默认的“application/x-www-form-urlencoded”,还是“application/json;”然后再一篇博客中看到,微信提供的接口入参格式为“application/json”。
  • 锁定了入参格式,但是再postMan上我是把所有的入参格式试了一遍的呀,那再试试入参里面去掉access_token呢?
  • ok,大功告成。终于见到了正常的返回数据。
  • 总结两点:

1、入参格式采用“application/json; charset=utf-8”;

2、需要拼接access_token的接口入参请干掉access_token如上文中的代码



如果你想要了解更多关于云开发CloudBase相关的技术故事/技术实战经验,请扫码关注【腾讯云云开发】公众号~

原文地址:https://www.cnblogs.com/CloudBase/p/11551625.html

时间: 2024-10-12 19:46:32

小程序·云开发的HTTP API调用丨实战的相关文章

小程序云开发调用HTTP请求中got第三方库使用失败解决方法

小程序云开发调用HTTP请求中got第三方库使用失败解决方法 错误代码 {"errorCode":1,"errorMessage":"user code exception caught","stackTrace":"The \"original\" argument must be of type function"} 替换方案 // 云函数入口文件 const cloud = req

微信小程序云开发入门到发布上线

初始化项目 起步说明[非小白教程] 适合人群[建议快速看文档,对着写一遍] 看过官方文档,并简单的写过 起步教程 云开发文档 熟悉vue/es6 小程序注册[微信公众平台] 获取appid[微信公众平台-开发-开发设置] 新建小程序云开发项目 新建项目选择一个空目录,填入 AppID(使用云开发能力必须填写 AppID) 勾选创建 "小程序云开发 " 点击新建即可得到一个展示云开发基础能力的示例小程序. 该小程序与普通 QuickStart 小程序有以下不同需注意: 无游客模式.也不可

微信小程序云开发-从0打造云音乐全栈小程序

第1章 首门小程序“云开发”课程,你值得学习本章主要介绍什么是小程序云开发以及学习云开发的重要性,并介绍项目的整体架构,真机演示项目功能,详细介绍整体课程安排.课程适用人群以及需要掌握的前置知识.通过本章的学习,能够使大家对本门课程有一个整体的了解.... 第2章 云开发介绍以及从0构建项目本章会详细介绍小程序云开发与Serverless,并介绍如何开通小程序云开发及控制台的功能,并且初始化项目代码,讲解airbnb/javascript代码规范. 第3章 播放列表功能实现本章完成歌单列表与歌曲

小程序云开发攻略,解决最棘手的问题

背景 最近小程序非常的火,应公司业务发展要求,开发维护了几款小程序,公司开发的小程序都是由后端提供的接口,开发繁琐而复杂,直到小程序出现了云开发,仔细研读了文档之后,欣喜不已,于是我着手开发了本人的第一款小程序 小程序云开发教程地址 点我查看>> 分析 云开发为开发者提供完整的原生云端支持和微信服务支持,弱化后端和运维概念,无需搭建服务器,使用平台提供的 API 进行核心业务开发,即可实现快速上线和迭代,同时这一能力,同开发者已经使用的云服务相互兼容,并不互斥. 优势 无需自建服务器,数据库,

小程序 · 云开发

9 月 11 日,微信开发者工具新增小程序「云开发」功能. 大多数开发者在开发应用时和部署服务时,无论是选择公有云还是自建数据中心,都需要提前考虑服务器.存储和数据库等需求,并且会花费时间精力在部署应用.依赖上.而通过「小程序·云开发」,开发者可以开发微信小程序.小游戏,无需搭建服务器,即可使用云端能力,实现小程序的快速上线和迭代. 「小程序·云开发」将以服务的方式为开发者提供如云函数.数据库.存储管理等所需功能,大大降低了小程序的开发门槛,仅需通过「小程序·云开发」提供的接口,就能实现因缺乏后

小程序云开发之新闻类项目分析

应该每一个前端开发者都有一颗全干全栈的心??吧. 那就让云开发满足你 云开发一出来就开始玩,云数据库,云函数,全栈的体验和开发速度,真的不是一般的爽. 接下来工作中要开发一款新闻类小程序,于是就开始了对头条君的调研,此篇文章,是我的个人总结和分析,欢迎大佬拍砖. 一. 准备 小程序云开发必须有小程序AppId才能使用,所以首先应先注册一个小程序账号(如果已有请忽略).设置->开发设置中的小程序AppId 开发工具:编辑器-vscode, 微信开发者工具 辅助工具: Markman:图标标注工具,

【微信小程序云开发】从陌生到熟悉

前言 微信小程序在9月10号正式上线了云开发的功能,弱化后端和运维概念,以前开发一个小程序需要申请一个小程序,准备一个https的域名,开发需要一个前端一个服务端,有了云开发只有申请一个小程序,一个前端就能搞定,真的是零成本. 云开发三大基础能力 云函数:运行在微信服务器上的函数,处理微信相关操作有天然优势,如获得用户信息异常方便(以前服务端解析很麻烦) 数据库:一个小程序可以直接操作的JSON数据库,可以直接操作数据库,不在需要服务端了. 存储:用来存储文件和图片 阅读本文之前最好对微信小程序

微信小程序云开发

使用微信小程序云开发,可以不需要后端的参与,前端直接使用数据库. 第一步,新建一个空的云开发项目 在project.config.json 文件可以看见 "miniprogramRoot": "miniprogram/",   表示为小程序页面的文件 "cloudfunctionRoot": "cloudfunctions/", 表示云函数文件,即 在云端定义一些函数,运行环境为 nodejs, 可以做一些运算操作,然后将结果

用小程序·云开发两天搭建mini论坛丨实战

笔者最近涉猎了小程序相关的知识,于是利用周末时间开发了一款类似于同事的小程序,深度体验了小程序云开发模式提供的云函数.数据库.存储三大能力.关于云开发,可参考文档:小程序·云开发. 个人感觉云开发带来的最大好处是鉴权流程的简化和对后端的弱化,所以像笔者这种从未接触过小程序开发的人也能够在周末两天时间内开发出一个功能完备.体验闭环的勉强能用的产品. 最后,本文并不是搬运官方文档,也不会详细介绍开发工具和云开发后台的使用,所以建议结合上面给出文档链接一起消化本文. 功能分析 该小程序功能目前较为简单