小程序雲開發之httpApi調用(返回「47001處理」)javascript
採用 nodejs + express 搭建web服務器,採用 axios 請求第三方 httpApi
經過應用生成器工具 express-generator 能夠快速建立一個應用的骨架。vue
主要的核心文件 routes/base.js(api設置),util/rq.js(axios封裝),views/base.pug(接口文檔)java
|---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 (框架生成,項目核心)
// 模塊引用 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 }
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;
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調用已完成。node
簡單的利用vue+elementui作個雲開發小程序後臺管理頁面調用下上面的接口。ios
咱們看下效果以下:web
至此小程序雲開發----httpApi調用完工。數據庫
在post獲取數據庫集合信息時,第三方返回錯誤碼「47001」
在網上查了下,有不少遇到這個問題的。但如何解決說的大都不明不白,或者未解決,或者解決了帖子未更新。express
本人遇到該問題時,先是在官方社區搜索了相關提問,發現官方回覆,在postman上嘗試調用若是無恙請檢查自身代碼。npm
{ 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,大功告成。終於見到了正常的返回數據。
總結兩點:
一、入參格式採用「application/json; charset=utf-8」;
二、須要拼接access_token的接口入參請幹掉access_token如上文中的代碼
若是你想要了解更多關於雲開發CloudBase相關的技術故事/技術實戰經驗,請掃碼關注【騰訊云云開發】公衆號~