Skip to content

API調用問題大集合!

本頁面收集了使用uni-app開發過程中常見的API調用相關問題及解決方案,讓你輕鬆搞定各種API難題!

目錄

API調用基礎問題

Q1: 如何正確引入和使用uni-app的API?

問題描述:初學者常常不清楚如何正確引入和使用uni-app提供的API。

解決方案:uni-app的API是全局對象,可以直接在代碼中使用,無需導入。

js
// 正確使用方式 - 直接調用
uni.showToast({
  title: '操作成功',
  icon: 'success'
});

// 錯誤使用方式 - 不需要導入
import uni from 'uni-app'; // 錯誤,不需要這樣導入

Q2: API返回的Promise如何正確處理?

問題描述:很多開發者不清楚uni-app API的Promise用法。

解決方案:大多數uni-app API支持Promise風格調用,可以使用async/await或then/catch處理。

js
// 方式一:使用async/await
async function getUserInfo() {
  try {
    const res = await uni.getUserProfile({
      desc: '用於完善用戶資料'
    });
    console.log(res.userInfo);
  } catch (e) {
    console.error(e);
  }
}

// 方式二:使用then/catch
uni.getUserProfile({
  desc: '用於完善用戶資料'
})
.then(res => {
  console.log(res.userInfo);
})
.catch(err => {
  console.error(err);
});

網絡API問題

Q3: uni.request請求失敗或超時怎麼辦?

問題描述:使用uni.request發起網絡請求時遇到失敗或超時問題。

解決方案

  1. 檢查網絡連接和服務器狀態
  2. 設置合理的超時時間
  3. 添加重試機制
  4. 確保請求URL的協議正確(https/http)
  5. 檢查是否有跨域問題
js
// 帶重試機制的請求示例
function requestWithRetry(options, maxRetries = 3) {
  return new Promise((resolve, reject) => {
    let retryCount = 0;
    
    function attempt() {
      uni.request({
        ...options,
        success: (res) => {
          resolve(res);
        },
        fail: (err) => {
          retryCount++;
          if (retryCount <= maxRetries) {
            console.log(`請求失敗,第${retryCount}次重試`);
            setTimeout(() => {
              attempt();
            }, 1000 * retryCount); // 遞增重試延遲
          } else {
            reject(err);
          }
        }
      });
    }
    
    attempt();
  });
}

Q4: 小程序環境下API請求域名限制問題

問題描述:在小程序環境中,API請求域名必須在小程序管理後台配置,否則請求會失敗。

解決方案

  1. 在小程序管理後台的"開發設置"中添加服務器域名
  2. 開發階段可以在開發工具中勾選"不校驗合法域名"選項
  3. 使用小程序雲開發避免域名限制
js
// 根據環境判斷是否需要使用完整域名
const BASE_URL = process.env.NODE_ENV === 'development' 
  ? '/api' 
  : 'https://api.example.com';

uni.request({
  url: `${BASE_URL}/user/info`,
  // 其他配置...
});

存儲API問題

Q5: uni.setStorage和uni.setStorageSync有什麼區別?

問題描述:開發者常常不清楚同步和異步存儲API的區別和使用場景。

解決方案

  • uni.setStorage是異步API,不會阻塞主線程,適合存儲大量數據
  • uni.setStorageSync是同步API,會阻塞主線程,適合存儲少量關鍵數據
js
// 異步存儲 - 推薦用法
uni.setStorage({
  key: 'userInfo',
  data: userInfo,
  success: function() {
    console.log('存儲成功');
  }
});

// 同步存儲 - 少量數據時使用
try {
  uni.setStorageSync('token', token);
} catch (e) {
  console.error(e);
}

Q6: 存儲空間限制問題

問題描述:小程序環境下存儲空間有限制(一般為10MB),超出限制會導致存儲失敗。

解決方案

  1. 只存儲必要的數據
  2. 大文件使用雲存儲
  3. 定期清理不必要的緩存數據
  4. 實現存儲空間管理機制
js
// 存儲空間管理示例
function safeStorage(key, data) {
  try {
    // 先嘗試存儲
    uni.setStorageSync(key, data);
  } catch (e) {
    // 如果失敗,清理部分舊數據後再嘗試
    const keys = uni.getStorageInfoSync().keys;
    // 按時間排序,清理最早的數據
    const oldKeys = keys.filter(k => k.startsWith('cache_')).sort();
    if (oldKeys.length > 0) {
      uni.removeStorageSync(oldKeys[0]);
      // 重試存儲
      uni.setStorageSync(key, data);
    }
  }
}

位置和地圖API問題

Q7: 獲取位置信息失敗

問題描述:調用uni.getLocation API獲取用戶位置信息失敗。

解決方案

  1. 確保已在manifest.json中配置了地理位置權限
  2. 檢查用戶是否授權了位置權限
  3. 在真機上測試,模擬器可能無法正常獲取位置
  4. 考慮位置服務是否開啟
js
// 獲取位置前先檢查權限
uni.getSetting({
  success: (res) => {
    if (!res.authSetting['scope.userLocation']) {
      uni.authorize({
        scope: 'scope.userLocation',
        success: () => {
          getLocation();
        },
        fail: () => {
          uni.showModal({
            title: '提示',
            content: '需要獲取您的地理位置,請確認授權',
            success: (res) => {
              if (res.confirm) {
                uni.openSetting();
              }
            }
          });
        }
      });
    } else {
      getLocation();
    }
  }
});

function getLocation() {
  uni.getLocation({
    type: 'gcj02',
    success: (res) => {
      const { latitude, longitude } = res;
      console.log(`當前位置:${latitude}, ${longitude}`);
    },
    fail: (err) => {
      console.error('獲取位置失敗', err);
    }
  });
}

文件API問題

Q8: 文件上傳失敗問題

問題描述:使用uni.uploadFile上傳文件時失敗。

解決方案

  1. 檢查文件路徑是否正確
  2. 確認服務器端是否正確配置了文件上傳接口
  3. 檢查文件大小是否超出限制
  4. 確保網絡連接穩定
  5. 添加上傳進度監控和重試機制
js
// 帶進度監控和重試的文件上傳
function uploadFileWithRetry(options, maxRetries = 3) {
  return new Promise((resolve, reject) => {
    let retryCount = 0;
    
    function attempt() {
      const uploadTask = uni.uploadFile({
        ...options,
        success: (res) => {
          resolve(res);
        },
        fail: (err) => {
          retryCount++;
          if (retryCount <= maxRetries) {
            console.log(`上傳失敗,第${retryCount}次重試`);
            setTimeout(() => {
              attempt();
            }, 1000 * retryCount);
          } else {
            reject(err);
          }
        }
      });
      
      uploadTask.onProgressUpdate((res) => {
        console.log('上傳進度', res.progress);
        if (options.onProgress) {
          options.onProgress(res.progress);
        }
      });
    }
    
    attempt();
  });
}

// 使用示例
uploadFileWithRetry({
  url: 'https://api.example.com/upload',
  filePath: tempFilePath,
  name: 'file',
  onProgress: (progress) => {
    this.uploadProgress = progress;
  }
}).then(res => {
  console.log('上傳成功', res);
}).catch(err => {
  console.error('上傳失敗', err);
});

界面API問題

Q9: uni.showToast和uni.showModal使用時機

問題描述:開發者常常不清楚何時使用toast,何時使用modal。

解決方案

  • uni.showToast:用於簡短的操作結果反饋,自動消失
  • uni.showModal:用於需要用戶確認或選擇的場景,不會自動消失
js
// 操作成功反饋 - 使用Toast
uni.showToast({
  title: '保存成功',
  icon: 'success',
  duration: 2000
});

// 需要用戶確認的場景 - 使用Modal
uni.showModal({
  title: '提示',
  content: '是否確認刪除該條記錄?',
  success: (res) => {
    if (res.confirm) {
      deleteRecord();
    }
  }
});

Q10: 頁面導航API使用問題

問題描述:uni.navigateTo、uni.redirectTo、uni.switchTab等導航API使用混淆。

解決方案

  • uni.navigateTo:保留當前頁面,跳轉到應用內的某個頁面
  • uni.redirectTo:關閉當前頁面,跳轉到應用內的某個頁面
  • uni.switchTab:跳轉到 tabBar 頁面,並關閉其他所有非 tabBar 頁面
  • uni.navigateBack:關閉當前頁面,返回上一頁面或多級頁面
  • uni.reLaunch:關閉所有頁面,打開到應用內的某個頁面
js
// 正確使用導航API
// 1. 普通頁面跳轉,保留當前頁面
uni.navigateTo({
  url: '/pages/detail/detail?id=1'
});

// 2. 替換當前頁面
uni.redirectTo({
  url: '/pages/result/result?status=success'
});

// 3. 跳轉到tabBar頁面
uni.switchTab({
  url: '/pages/home/home'
});

// 4. 返回上一頁
uni.navigateBack({
  delta: 1
});

// 5. 重啟到某個頁面
uni.reLaunch({
  url: '/pages/login/login'
});

平台差異API問題

Q11: 如何處理不同平台特有的API?

問題描述:某些API只在特定平台可用,直接調用會導致在其他平台報錯。

解決方案:使用條件編譯或運行時平台判斷。

js
// 方法1:使用條件編譯
// #ifdef MP-WEIXIN
wx.requestSubscribeMessage({
  tmplIds: ['xxx'],
  success: (res) => {
    console.log('訂閱消息成功');
  }
});
// #endif

// 方法2:運行時判斷
if (uni.getSystemInfoSync().platform === 'android') {
  // 僅安卓平台執行的代碼
  console.log('當前是安卓平台');
}

// 方法3:封裝跨平台API
function shareContent(options) {
  // #ifdef MP-WEIXIN
  wx.shareAppMessage(options);
  // #endif
  
  // #ifdef APP-PLUS
  uni.share({
    provider: 'weixin',
    ...options
  });
  // #endif
  
  // #ifdef H5
  // H5環境下的分享邏輯
  // #endif
}

Q12: 如何優雅地處理API的平台兼容性?

問題描述:不同平台的API參數和行為可能有差異,導致兼容性問題。

解決方案:創建平台適配層,統一API調用接口。

js
// 創建API適配層示例
const api = {
  // 統一的文件選擇API
  chooseFile: function(options = {}) {
    // #ifdef APP-PLUS || H5
    return uni.chooseFile({
      count: options.count || 1,
      extension: options.extension || [],
      ...options
    });
    // #endif
    
    // #ifdef MP
    return uni.chooseMessageFile({
      count: options.count || 1,
      type: options.type || 'all',
      ...options
    });
    // #endif
  },
  
  // 統一的分享API
  share: function(options = {}) {
    return new Promise((resolve, reject) => {
      // #ifdef APP-PLUS
      uni.share({
        provider: options.provider || 'weixin',
        scene: options.scene || 'WXSceneSession',
        type: options.type || 0,
        title: options.title,
        summary: options.summary || options.desc,
        imageUrl: options.imageUrl,
        href: options.link,
        success: resolve,
        fail: reject
      });
      // #endif
      
      // #ifdef MP-WEIXIN
      wx.showShareMenu({
        withShareTicket: true,
        menus: ['shareAppMessage', 'shareTimeline'],
        success: resolve,
        fail: reject
      });
      // #endif
      
      // #ifdef H5
      // H5環境實現分享
      if (navigator.share && options.type === 'system') {
        navigator.share({
          title: options.title,
          text: options.summary || options.desc,
          url: options.link
        }).then(resolve).catch(reject);
      } else {
        // 使用自定義分享UI
        uni.showModal({
          title: '分享提示',
          content: '請點擊瀏覽器自帶的分享按鈕進行分享',
          showCancel: false,
          success: resolve,
          fail: reject
        });
      }
      // #endif
    });
  }
};

// 使用示例
api.chooseFile({
  count: 3,
  success: (res) => {
    console.log('選擇的文件', res.tempFiles);
  }
});

總結

在使用uni-app API時,需要注意以下幾點:

  1. 了解API特性:同步/異步、返回值、參數要求等
  2. 處理平台差異:使用條件編譯或運行時判斷
  3. 錯誤處理:添加try/catch或fail回調處理異常情況
  4. 權限管理:注意API可能需要的權限申請
  5. 性能優化:合理使用API,避免頻繁調用影響性能

如果您遇到本文未涵蓋的API問題,可以查閱uni-app官方API文檔或在社區中尋求幫助。

一次開發,多端部署 - 讓跨平台開發更簡單