我在較早期的隨筆中《微信小程序豆瓣電影項目的改造過程經(jīng)驗分享》介紹一個利用豆瓣接口獲取其電影資料的小程序,小程序的界面如下所示。

不過由于小程序被豆瓣端進(jìn)行調(diào)用接口,那么再運行小程序就有接口錯誤了,如下所示。

而我們一般都已經(jīng)在小程序的設(shè)置上添加了豆瓣的域名了

不過由于豆瓣官方對小程序端的限制,那么我們就無法進(jìn)行正常的接口數(shù)據(jù)獲取了。
我們可以從豆瓣的接口文檔中了解到,豆瓣提供了不少電影相關(guān)的數(shù)據(jù)接口,這個是我們用來練手或者加工小程序的很好數(shù)據(jù)來源,它的接口如下所示。
豆瓣電影接口的API地址如下所示:https://developers.douban.com/wiki/?title=movie_v2

既然小程序段無法再通過接口方式獲取電影數(shù)據(jù),但測試電腦端是沒問題的,那么我們可以利用自己的API接口對豆瓣接口進(jìn)行封裝,從而實現(xiàn)接口數(shù)據(jù)的代理接口處理,為了方便,我們還是盡可能把代理接口弄得通用一些,以便其他接口也可以通過中轉(zhuǎn)方式獲取,提高中轉(zhuǎn)接口的通用性。
我們先來看看小程序端的JS端對接口的調(diào)用代碼,如下是獲取電影數(shù)據(jù)的其中一個接口,如下所示。
//通用的熱映、待映的獲取方式
fetchFilms: function(page, url, city, start, count) {
return new Promise((resolve, reject) => {
var that = page;
var json = {city: city, start: start, count: count };
var type = "json";//特殊設(shè)置,默認(rèn)是application/json
if (that.data.hasMore) {
app.utils.get(url, json, type).then(res => {
if(res.subjects.length === 0){
that.setData({
hasMore: false,
})
}else{
that.setData({
films: that.data.films.concat(res.subjects),
start: that.data.start + res.subjects.length,
showLoading: false
})
}
wx.stopPullDownRefresh();
resolve(res);
})
}
})
},
這里面核心是通過調(diào)用 app.utils.get(url, json, type) 的方式來處理對API的GET方式調(diào)用,我們再來看看這個Get方式的調(diào)用
//發(fā)布的接口
module.exports = {
Promise,makeArray,getUserInfo,
get:requestGet,post:requestPost,request,decodeHtml,
setStorage,getStorage,getLocation,getCityName,
getDate,getTime,formatTime,getDateDiff,getWeek,get2,post2
}
這個 util.js 里面公布的get接口就是 requestGet函數(shù),我們用了別名的方式,它的詳細(xì)代碼如下所示
function requestGet(url,data,type){
return request(url,'GET',data,type)
}
function requestPost(url,data,type){
return request(url,'POST',data,type)
}
//封裝Request請求方法
function request(url, method, data = {}, type='application/json'){
wx.showNavigationBarLoading();
return new Promise((resove,reject) => {
wx.request({
url: url,
data: data,
header: {'Content-Type': type},
method: method.toUpperCase(), // OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT
success: function(res){
wx.hideNavigationBarLoading()
resove(res.data)
},
fail: function(msg) {
console.log('reqest error',msg)
wx.hideNavigationBarLoading()
reject('fail')
}
})
})
}
通過以上的分析,如果我們需要避免修改太多地方,那么我們把 app.utils.get(url, json, type) 里面的 get 修改為 get2 的方式就好了,其他參數(shù)變化等中轉(zhuǎn)信息,封裝在 get2 函數(shù)內(nèi)部就好,這樣我們只需修改一個函數(shù)名稱就是了。
中轉(zhuǎn)接口后,處理的方式有所不同,我們需要把整個帶有參數(shù)的地址作為一個完整的URL傳遞給服務(wù)器接口(需要URL編碼,否則無法獲得參數(shù)),而且由于通用接口無法返回JSON格式,我們還需要返回的字符串內(nèi)容進(jìn)行JSON格式的轉(zhuǎn)換。
//使用內(nèi)部接口進(jìn)行中轉(zhuǎn)
var wrapper_get_url = 'http://localhost:27206/api/third/httpwrapper/httpget';
function get2(url, data = {}, type='application/json') {
var newdata = {};
var newUrl = wrapper_get_url + "?url=" + encodeURIComponent(url + "?" + json2Form(data));
console.log(newUrl);
return new Promise((resolve, reject) => {
wx.request({
url: newUrl,
data: newdata,
headers: {'Content-Type': type},
success: function(res) {
//將中轉(zhuǎn)接口返回的字符串轉(zhuǎn)換為JSON對象
var res = convertJson(res.data);
resolve(res)
},
fail: function(res) {
//將中轉(zhuǎn)接口返回的字符串轉(zhuǎn)換為JSON對象
var res = convertJson(res.data);
reject(res)
}
})
})
}
上面的代碼我們使用自己的本地接口進(jìn)行測試,其中需要提交的URL是我們服務(wù)器的URL,原先的URL+數(shù)據(jù)組合為一個新的參數(shù)傳遞給服務(wù)器使用。
另外,由于返回的中轉(zhuǎn)接口數(shù)據(jù)為字符串信息,非JSON格式,那么還需要將中轉(zhuǎn)接口返回的字符串轉(zhuǎn)換為JSON對象。
//轉(zhuǎn)義字符串為JSON對象
function convertJson(res) {
//將中轉(zhuǎn)獲取到的字符串轉(zhuǎn)換為JSON對象
var jsonStr = JSON.stringify(res);
var jsonStrSym = jsonStr.replace('/', '\\');
var jsondata = JSON.parse(JSON.parse(jsonStr));
console.log(jsondata);
return jsondata;
};
以上就是完整的前端代碼了,通過上面的處理,我們可以正常的獲得接口的數(shù)據(jù),并可以正常的展示了,正式發(fā)布的時候,我們修改用上自己的服務(wù)器域名地址即可發(fā)布使用了。
前面介紹了小程序的前端代碼修改,只需要引入一個新的函數(shù)就可以實現(xiàn)數(shù)據(jù)的中轉(zhuǎn)獲取了,后端我們自然配合這個接口實現(xiàn)數(shù)據(jù)的獲取即可。
我們在后端增加一個控制器,增加對應(yīng)的接口定義,如下代碼所示。
namespace WebAPI.Areas.Third.Controllers
{
/// <summary>
/// 對第三方的Http接口數(shù)據(jù)進(jìn)行包裝,獲取數(shù)據(jù),避免小程序并禁止獲取數(shù)據(jù)的問題
/// </summary>
public class HttpWrapperController : BaseApiController
{
/// <summary>
/// get方式獲取數(shù)據(jù)
/// </summary>
/// <param name="url">接口URL</param>
/// <returns></returns>
[HttpGet]
public string HttpGet(string url)
{
HttpHelper helper = new HttpHelper();
var html = helper.GetHtml(url, "", false);
return html;
}
是不是比較簡單,這樣就可以實現(xiàn)通用的接口數(shù)據(jù)中轉(zhuǎn)了。
最后測試得到的正常數(shù)據(jù)展示界面,如下所示。