阿里云主机折上折
  • 微信号
您当前的位置:网站首页 > 网络请求(uni.request)

网络请求(uni.request)

作者:陈川 阅读数:13336人阅读 分类: uni-app

uni-app 是一个使用 Vue.js 开发跨平台应用的框架,支持编译到多个平台。uni.request 是 uni-app 提供的网络请求 API,用于发起 HTTP 请求。它的用法类似于微信小程序的 wx.request,但在 uni-app 中可以跨平台使用。

uni.request 的基本用法

uni.request 是一个异步方法,用于发送 HTTP 请求。它的基本语法如下:

uni.request({
  url: 'https://example.com/api',
  method: 'GET',
  data: {
    key1: 'value1',
    key2: 'value2'
  },
  header: {
    'Content-Type': 'application/json'
  },
  success: (res) => {
    console.log(res.data);
  },
  fail: (err) => {
    console.error(err);
  },
  complete: () => {
    console.log('请求完成');
  }
});

参数说明

  • url:请求的接口地址,必需。
  • method:请求方法,如 GETPOSTPUTDELETE 等,默认为 GET
  • data:请求的参数,可以是对象或字符串。
  • header:请求头,可以设置 Content-Type 等。
  • success:请求成功的回调函数,返回响应数据。
  • fail:请求失败的回调函数,返回错误信息。
  • complete:请求完成的回调函数(无论成功或失败都会执行)。

发送 GET 请求

GET 请求通常用于获取数据。以下是一个获取用户信息的示例:

uni.request({
  url: 'https://api.example.com/users',
  method: 'GET',
  data: {
    userId: 123
  },
  success: (res) => {
    console.log('用户信息:', res.data);
  },
  fail: (err) => {
    console.error('请求失败:', err);
  }
});

发送 POST 请求

POST 请求通常用于提交数据。以下是一个提交表单的示例:

uni.request({
  url: 'https://api.example.com/submit',
  method: 'POST',
  data: {
    name: '张三',
    age: 25
  },
  header: {
    'Content-Type': 'application/json'
  },
  success: (res) => {
    console.log('提交成功:', res.data);
  },
  fail: (err) => {
    console.error('提交失败:', err);
  }
});

设置请求头

请求头可以通过 header 参数设置。例如,设置 Authorization 用于身份验证:

uni.request({
  url: 'https://api.example.com/protected',
  method: 'GET',
  header: {
    'Authorization': 'Bearer your_token_here'
  },
  success: (res) => {
    console.log('受保护的数据:', res.data);
  }
});

处理响应数据

success 回调函数的参数 res 包含以下字段:

  • data:服务器返回的数据。
  • statusCode:HTTP 状态码。
  • header:响应头。
uni.request({
  url: 'https://api.example.com/data',
  success: (res) => {
    console.log('状态码:', res.statusCode);
    console.log('响应头:', res.header);
    console.log('数据:', res.data);
  }
});

错误处理

通过 fail 回调可以捕获请求失败的情况:

uni.request({
  url: 'https://api.example.com/error',
  fail: (err) => {
    console.error('请求出错:', err);
    // 可以在这里显示错误提示
    uni.showToast({
      title: '网络请求失败',
      icon: 'none'
    });
  }
});

使用 async/await

uni.request 也支持 Promise 风格调用,可以与 async/await 结合使用:

async function fetchData() {
  try {
    const res = await uni.request({
      url: 'https://api.example.com/data',
      method: 'GET'
    });
    console.log('数据:', res[1].data); // 注意:返回的是一个数组 [err, res]
  } catch (err) {
    console.error('请求失败:', err);
  }
}

fetchData();

请求超时设置

可以通过 timeout 参数设置请求超时时间(单位:毫秒):

uni.request({
  url: 'https://api.example.com/slow',
  timeout: 5000, // 5秒超时
  success: (res) => {
    console.log('请求成功:', res.data);
  },
  fail: (err) => {
    console.error('请求超时或失败:', err);
  }
});

文件上传

uni.uploadFile 用于文件上传,但也可以通过 uni.request 实现文件上传(需手动处理 FormData):

uni.chooseImage({
  success: (chooseRes) => {
    const tempFilePaths = chooseRes.tempFilePaths;
    uni.request({
      url: 'https://api.example.com/upload',
      method: 'POST',
      filePath: tempFilePaths[0],
      name: 'file',
      formData: {
        userId: '123'
      },
      success: (uploadRes) => {
        console.log('上传成功:', uploadRes.data);
      }
    });
  }
});

拦截器

uni-app 本身不提供拦截器功能,但可以通过封装 uni.request 实现类似功能:

const request = (options) => {
  // 添加全局请求头
  const defaultHeader = {
    'X-Requested-With': 'XMLHttpRequest'
  };
  options.header = Object.assign(defaultHeader, options.header || {});

  // 添加 token
  const token = uni.getStorageSync('token');
  if (token) {
    options.header.Authorization = `Bearer ${token}`;
  }

  return new Promise((resolve, reject) => {
    uni.request({
      ...options,
      success: (res) => {
        if (res.statusCode >= 200 && res.statusCode < 300) {
          resolve(res.data);
        } else {
          reject(res);
        }
      },
      fail: (err) => {
        reject(err);
      }
    });
  });
};

// 使用封装后的 request
request({
  url: 'https://api.example.com/data',
  method: 'GET'
}).then(data => {
  console.log(data);
}).catch(err => {
  console.error(err);
});

跨域问题

在开发环境中,可能会遇到跨域问题。可以通过以下方式解决:

  1. manifest.json 中配置代理:
{
  "h5": {
    "devServer": {
      "proxy": {
        "/api": {
          "target": "https://api.example.com",
          "changeOrigin": true,
          "pathRewrite": {
            "^/api": ""
          }
        }
      }
    }
  }
}

然后在代码中请求 /api 路径即可。

  1. 后端设置 CORS 头。

实际应用示例

以下是一个完整的用户登录示例:

// 登录方法
async function login(username, password) {
  try {
    const res = await uni.request({
      url: 'https://api.example.com/login',
      method: 'POST',
      data: {
        username,
        password
      },
      header: {
        'Content-Type': 'application/json'
      }
    });

    const data = res[1].data;
    if (data.token) {
      uni.setStorageSync('token', data.token);
      uni.showToast({
        title: '登录成功',
        icon: 'success'
      });
      return true;
    } else {
      throw new Error(data.message || '登录失败');
    }
  } catch (err) {
    uni.showToast({
      title: err.message,
      icon: 'none'
    });
    return false;
  }
}

// 在页面中调用
login('admin', '123456').then(success => {
  if (success) {
    uni.navigateTo({
      url: '/pages/home/index'
    });
  }
});

性能优化建议

  1. 合理设置缓存:对于不常变动的数据,可以使用 uni.setStorage 缓存响应结果。
  2. 合并请求:减少请求次数,多个接口可以合并为一个。
  3. 取消请求:长时间未响应的请求应该取消,避免资源浪费。
  4. 压缩数据:与后端协商使用 gzip 压缩响应数据。
// 缓存示例
async function getCachedData() {
  const cacheKey = 'cached_data';
  const cachedData = uni.getStorageSync(cacheKey);
  if (cachedData) {
    return cachedData;
  }

  const res = await uni.request({
    url: 'https://api.example.com/data'
  });
  const data = res[1].data;
  uni.setStorageSync(cacheKey, data);
  return data;
}

注意事项

  1. 在微信小程序中,uni.requesturl 必须配置在 request 合法域名中。
  2. 在 H5 端,跨域问题需要后端配合解决或使用代理。
  3. data 参数如果是对象,会自动转换为查询字符串(GET)或请求体(POST)。
  4. 在支付宝小程序中,content-typeapplication/json 时需要手动将 data 转为 JSON 字符串。

高级用法

对于大型项目,可以进一步封装:

// http.js
const baseURL = 'https://api.example.com';

const http = {
  get(url, data) {
    return this.request('GET', url, data);
  },
  post(url, data) {
    return this.request('POST', url, data);
  },
  request(method, url, data) {
    return new Promise((resolve, reject) => {
      uni.request({
        url: baseURL + url,
        method,
        data,
        header: {
          'Authorization': `Bearer ${uni.getStorageSync('token')}`
        },
        success: (res) => {
          if (res.statusCode === 200) {
            resolve(res.data);
          } else {
            reject(res.data);
          }
        },
        fail: (err) => {
          reject(err);
        }
      });
    });
  }
};

export default http;

// 使用示例
import http from './http.js';

http.get('/users').then(data => {
  console.log(data);
}).catch(err => {
  console.error(err);
});

本站部分内容来自互联网,一切版权均归源网站或源作者所有。

如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn

前端川

前端川,陈川的代码茶馆🍵,专治各种不服的Bug退散符💻,日常贩卖秃头警告级的开发心得🛠️,附赠一行代码笑十年的摸鱼宝典🐟,偶尔掉落咖啡杯里泡开的像素级浪漫☕。‌