[TOC]
## 3.3 發起HTTPS網絡通信`wx.request`
小程序使用`wx.request`這個API,往服務器傳遞數據或者從服務器拉取信息。為了敘述方便,假設我們的服務器域名是test.com。
>[info] hy,封裝了JavaScript的XhttpRequest對象?通過Ajaxl來實現。
### 3.3.1 wx.request接口
從test.com服務器的getinfo接口拉取用戶信息,其代碼示例如下所示,詳細參數如表4-1所示。
代碼清單4-7 wx.request調用示例
~~~
wx.request({
url: 'https://test.com/getinfo',
success: function(res) {
console.log(res)// 服務器回包信息
}
})
~~~
:-: 表4-1 wx.request詳細參數
| 參數名 | 類型 | 必填 | 默認值 | 描述|
| --- | ---| --- | --- | --- |
| url | String | 是 | | 開發者服務器接口地址|
| data | Object/String | 否 | | 請求的參數 |
| header | Object | 否 | | 設置請求的 header,header 中不能設置 Referer,默認header['content-type'] = 'application/json'
| method | String | 否 | GET | (需大寫)有效值:OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT |
| dataType | String | 否 | json | 回包的內容格式,如果設為json,會嘗試對返回的數據做一次 JSON解析|
| success | Function | 否 | | 收到開發者服務成功返回的回調函數,其參數是一個Object,見表4-2。
| fail | Function | 否 | | 接口調用失敗的回調函數|
| complete | Function | 否 | | 接口調用結束的回調函數(調用成功、失敗都會執行)|
### 3.3.2 服務器要求
url參數是當前發起請求的服務器接口地址,小程序宿主環境要求request發起的網絡請求必須是https協議請求,因此開發者服務器必須提供HTTPS服務的接口,同時為了保證小程序不亂用任意域名的服務,wx.request請求的域名需要在小程序管理平臺進行配置[[配置參考]](https://developers.weixin.qq.com/miniprogram/dev/qcloud/qcloud.html#%E5%AF%BC%E5%85%A5-PHP-DEMO-%E5%92%8C%E9%85%8D%E7%BD%AE)( 登錄`mp.weixin.qq.com`,在設置, 開發設置里配置request的服務器域名,同時TLS版本需要支持1.2及以上。),如果小程序正式版使用wx.request請求未配置的域名,在控制臺會有相應的報錯。
一般我們在開發階段時,處于開發階段的服務器接口還沒部署到現網的域名下,經常會通過另一個域名來進行開發調試,考慮到這一點,為了方便開發者進行開發調試,開發者工具、小程序的開發版和小程序的體驗版在某些情況下允許`wx.request`(開發者工具需要勾選不校驗可信域名;小程序開發版和體驗版需要打開調試模式。)請求任意域名。
### 3.3.3 請求參數
通過wx.request這個API,有兩種方法把數據傳遞到服務器:
* 通過url上的參數
url是有長度限制的,其最大長度是1024字節,同時url上的參數需要拼接到字符串里,參數的值還需要做一次urlEncode。
* 通過data參數
代碼清單4-8 wx.request調用示例
~~~
// 通過url參數傳遞數據
wx.request({
url:'https://test.com/getinfo?id=1&version=1.0.0',
success: function(res) {
console.log(res)// 服務器回包信息
}
})
// 通過data參數傳遞數據
wx.request({
url: 'https://test.com/getinfo',
data: { id:1, version:'1.0.0' },
success: function(res) {
console.log(res)// 服務器回包信息
}
})
~~~
兩種實現方式在HTTP GET請求的情況下表現幾乎是一樣的。但向服務端發送的數據超過1024字節時,就要采用HTTPPOST的形式,此時傳遞的數據就必須要使用data參數,基于這個情況,一般建議需要傳遞數據時,使用data參數來傳遞。
需要傳一些比較復雜的數據結構到后臺的時候,用JSON格式會更加合適。此時可以在wx.request的`header`參數設置content-type頭部為application/json,小程序發起的請求的包體內容就是data參數對應的JSON字符串,代碼示例如下。
代碼清單4-9 wx.request發起POST請求包體使用json格式
~~~
// 請求的包體為 {"a":{"b":[1,2,3],"c":{"d":"test"}}}
wx.request({
url: 'https://test.com/postdata',
method: 'POST',
header: { 'content-type': 'application/json'},
data: {
a: {
b: [1, 2, 3],
c: { d: "test" }
}
},
success: function(res) {
console.log(res)// 服務器回包信息
}
})
~~~
### 3.3.4 收到回包
通過wx.request發送請求后,服務器處理請求并返回HTTP包,小程序端收到回包后會觸發success回調,同時回調會帶上一個Object信息,詳細參數表4-2所示。
:-: 表4-2 wx.request的success返回參數
| 參數名 | 類型 | 描述 |
| --- | --- | --- |
| data | Object/String | 開發者服務器返回的數據 |
| statusCode | Number | 開發者服務器返回的 HTTP 狀態碼 |
| header | Object | 開發者服務器返回的 HTTP Response Header |
>[danger] 只要成功收到服務器返回,無論HTTP狀態碼是多少都會進入success回調。因此開發者需要自己通過對回包的返回碼進行判斷后再執行后續的業務邏輯。
success回調的參數data字段類型是根據header\['content-type']決定的,默認`header['content-type']是'application/json'`,在觸發success回調前,小程序宿主環境會對data字段的值做JSON解析,如果解析成功,那么data字段的值會被設置成解析后的Object對象,其他情況data字段都是String類型,其值為HTTP回包包體。
### 3.3.5 一般使用技巧
1. 設置超時時間
小程序request默認超時時間是60秒,一般來說,可能在等待3秒后還沒收到回包就需要給用戶一個明確的服務不可用的提示。在小程序項目根目錄里邊的app.json可以指定request的超時時間。
代碼清單4-10 app.json指定wx.requset超時時間為3000毫秒
~~~
{
"networkTimeout": {
"request": 3000
}
}
~~~
2. 請求前后的狀態處理
大部分場景可能是這樣的,用戶點擊一個按鈕,界面出現“加載中...”的Loading界面,然后發送一個請求到后臺,后臺返回成功直接進入下一個業務邏輯處理,后臺返回失敗或者網絡異常等情況則顯示一個“系統錯誤”的Toast,同時一開始的Loading界面會消失。我們給出一個常見的wx.request的示例代碼,如下所示。
代碼清單4-11 wx.request常見的示例代碼
~~~
var hasClick = false;
Page({
tap: function() {
if (hasClick) {
return
}
hasClick = true
wx.showLoading()
wx.request({
url: 'https://test.com/getinfo',
method: 'POST',
header: { 'content-type':'application/json' },
data: { },
success: function (res) {
if (res.statusCode === 200) {
console.log(res.data)// 服務器回包內容
}
},
fail: function (res) {
wx.showToast({ title: '系統錯誤' })
},
complete: function (res) {
wx.hideLoading()
hasClick = false
}
})
}
})
~~~
為了防止用戶極快速度觸發兩次tap回調,我們還加了一個hasClick的“鎖”,在開始請求前檢查是否已經發起過請求,如果沒有才發起這次請求,等到請求返回之后再把鎖的狀態恢復回去。
### 3.3.6 排查異常的方法
在使用wx.request接口我們會經常遇到無法發起請求或者服務器無法收到請求的情況,我們羅列排查這個問題的一般方法:
1. 檢查手機網絡狀態以及wifi連接點是否工作正常。
2. 檢查小程序是否為開發版或者體驗版,因為開發版和體驗版的小程序不會校驗域名。
3. 檢查對應請求的HTTPS證書是否有效,同時TLS的版本必須支持1.2及以上版本,可以在開發者工具的console面板輸入showRequestInfo()查看相關信息。
4. 域名不要使用IP地址或者localhost,并且不能帶端口號,同時域名需要經過ICP備案。
5. 檢查app.json配置的超時時間配置是否太短,超時時間太短會導致還沒收到回報就觸發fail回調。
6. 檢查發出去的請求是否302到其他域名的接口,這種302的情況會被視為請求別的域名接口導致無法發起請求。
- 微信
- 小程序
- 1. 代碼組成
- 1.1 JSON配置--'*.json'文件
- 1.2 WXML模板--'*.wxml'文件
- 1.3 WXSS樣式--'*.wxss'文件
- 1.4 JavaScript腳本--'*.js'文件
- 2. 客戶端運行
- 2.1 邏輯層和渲染層
- 2.1.1 邏輯層--App Service
- 2.1.2 渲染層/視圖層--View
- 2.1.3 通信模型
- 2.1.4 數據驅動
- 2.1.5 雙線程下的界面渲染
- 2.2 程序與頁面
- 2.3 組件
- 2.4 API
- 2.5 事件
- 2.6 兼容
- 3. 應用設計
- 3.1 Flex布局
- 3.2 界面常見的交互反饋
- 3.3 發起HTTPS網絡通信--wx.request
- 3.4 微信登錄
- 3.5 本地數據緩存
- 3.6 設備能力
- 4. 小程序的協同工作和發布
- 4.1 協同工作
- 4.2 用戶體驗審視
- 4.3 發布
- 4.4 運營
- 5. 底層框架
- 5.1 雙線程模型
- 5.2 組件系統--Exparser框架
- 5.3 原生組件
- 5.4 小程序與客戶端通信原理
- 6. 運行和性能優化
- 6.1 啟動--代碼加載
- 6.2 頁面準備
- 6.3 數據通信
- 6.4 視圖層渲染
- 6.5 原生組件通信
- 7. 小程序基礎庫的更新迭代
- 8. 微信開發者工具
- 騰訊云支持
- wafer
- Wafer2 快速開發 Demo - PHP
- WXAPI
- api列表