小程序引入服务器js,小程序云开发 ----httpApi 调用 (基于 Node.JS 搭建 Web 服务器)...

小程序云开发 ----httpApi 调用 (基于 Node.JS 搭建 Web 服务器)

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

技术栈

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

Node.JS

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)// 模块引用

letaxios=require("axios")

letqs=require("qs")

// 变量声明

constCONFKEY="dev"

constBASECONF={

"dev":{

baseUrl:'https://api.weixin.qq.com/',

},

"prod":{

baseUrl:'https://api.weixin.qq.com/'

}

}[CONFKEY]

// 创建 rq 请求并设置基础信息

constrq=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=>{

// 有需要的, 在此处拦截请求入参进行处理

returnreq

},error=>{

returnPromise.reject(error)

})

// axios 返回信息拦截器

rq.interceptors.response.use(res=>{

returnres.data

},error=>{

returnPromise.reject(error)

})

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

get(url,params){// axios.get(url,config)

returnrq.get(url,{

params:params

})

},

post(url,params={}){

returnrq({// axios(config)

url:url,

method:'post',

data:params

})

}

}

module.exports={

$rq

}

API 设置 (routes/base.JS)varexpress=require('express');

varrouter=express.Router();

var{$rq}=require("../util/rq")

letresult=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

leturlParam={// appID,secret 信息最好是不暴露在外故在此处直接写死即可

grant_type:"client_credential",

appid:"appid",

secret:"secret"

};

$rq.get("cgi-bin/token",urlParam).then(response=>{

global.TOKEN_INFO=response// global Node.JS 全局对象, 占用内存

letr=result.createResult(true,response);// 返回结果包装成固定格式

res.JSON(r);

}).catch(err=>{

letr=result.createResult(false,err);

res.JSON(r);

console.log(err)

})

});

router.get('/getdatabase',function(req,res,next){// 获取指定云环境集合信息

leturlParam={// 获取 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=>{

letr=result.createResult(true,response);

res.JSON(r);

}).catch(err=>{

letr=result.createResult(false,err);

res.JSON(r);

// console.log(err)

})

});

module.exports=router;

配置 App.JS 使路由及接口生效 (仅)varcreateError=require('http-errors');// 处理错误

varexpress=require('express');

varpath=require('path');// 路径

varcookieParser=require('cookie-parser');// cookie

varlogger=require('morgan');// 日志

varsassMiddleware=require('node-sass-middleware');// Sass 中间件

varindexRouter=require('./routes/index');// index 路由

varbaseRouter=require('./routes/base')// base 路由

varApp=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 做个云开发小程序后台管理页面调用下上面的接口.

我们看下效果如下:

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

ab7653affab982b574eb7acc55df2e04.gif

后台管理环境

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

本地启动接口服务

ab7653affab982b574eb7acc55df2e04.gif

本地启动接口服务

本地接口调用结果

ab7653affab982b574eb7acc55df2e04.gif

本地接口调用结果

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

ab7653affab982b574eb7acc55df2e04.gif

服务器调用结果

ok, 至此小程序云开发 ----httpApi 调用完工.

过程中遇到的问题

在 post 获取数据库集合信息时, 第三方返回错误码 "47001"

在网上查了下, 有很多遇到这个问题的. 但如何解决说的大都不明不白, 或者未解决, 或者解决了帖子未更新.

本人遇到该问题时, 先是在官方社区搜索了相关提问, 发现官方回复, 在 postman 上尝试调用如果无恙请检查自身代码.

ok, 依言自行在 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 如上文中的代码

ok, 这次真的结束了. 如果对你有用别忘了点个赞再走哈...

来源: http://www.jianshu.com/p/918c3074d062

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值