CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-tarojs--taro-h5

H5端API库,为Taro跨端开发框架提供Web/H5端的API实现

Pending
Overview
Eval results
Files

network.mddocs/

Network APIs

Comprehensive networking capabilities including HTTP requests with interceptor support, designed for web environments using modern fetch API with Mini Program compatibility.

Capabilities

HTTP Request API

Full-featured HTTP client supporting all standard methods, headers, data formats, and advanced options.

/**
 * Make HTTP request with full configuration support
 * @param options - Request configuration options
 * @returns Promise resolving to response with data, status, and headers
 */
function request(options: RequestOption): Promise<RequestResult>;

interface RequestOption {
  /** Target URL for the request (required) */
  url: string;
  /** Request body data (JSON serialized for non-GET requests) */
  data?: any;
  /** HTTP headers object */
  header?: Record<string, string>;
  /** HTTP method (default: 'GET') */
  method?: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'HEAD' | 'OPTIONS';
  /** Expected response data type (default: 'json') */
  dataType?: 'json' | 'text' | 'base64';
  /** Response type for binary data (default: 'text') */
  responseType?: 'text' | 'json' | 'arraybuffer';
  /** Request timeout in milliseconds (default: 60000) */
  timeout?: number;
  /** Enable HTTP/2 support (browser dependent) */
  enableHttp2?: boolean;
  /** Enable QUIC support (browser dependent) */
  enableQuic?: boolean;
  /** Enable response caching (browser dependent) */
  enableCache?: boolean;
  /** Enable credentials for cross-origin requests */
  credentials?: boolean;
  /** Success callback function */
  success?: (result: RequestResult) => void;
  /** Failure callback function */
  fail?: (error: any) => void;
  /** Completion callback function */
  complete?: (result: RequestResult | any) => void;
}

interface RequestResult {
  /** Response data (parsed based on dataType) */
  data: any;
  /** HTTP status code */
  statusCode: number;
  /** Response headers object */
  header: Record<string, string>;
  /** Response cookies (if any) */
  cookies?: string[];
  /** Error message (if request failed) */
  errMsg?: string;
}

Usage Examples:

import { request } from "@tarojs/taro-h5";

// Basic GET request
const getUserData = async (userId: string) => {
  try {
    const response = await request({
      url: `https://api.example.com/users/${userId}`,
      method: 'GET',
      header: {
        'Authorization': 'Bearer token123',
        'Content-Type': 'application/json'
      }
    });
    
    console.log('User data:', response.data);
    console.log('Status:', response.statusCode);
    return response.data;
  } catch (error) {
    console.error('Failed to fetch user:', error);
    throw error;
  }
};

// POST request with data
const createUser = async (userData: any) => {
  const response = await request({
    url: 'https://api.example.com/users',
    method: 'POST',
    data: userData,
    header: {
      'Content-Type': 'application/json',
      'Authorization': 'Bearer token123'
    },
    timeout: 10000
  });
  
  return response.data;
};

// PUT request for updates
const updateUserProfile = async (userId: string, profileData: any) => {
  const response = await request({
    url: `https://api.example.com/users/${userId}`,
    method: 'PUT',
    data: profileData,
    header: {
      'Content-Type': 'application/json',
      'X-Request-ID': Date.now().toString()
    }
  });
  
  return response.statusCode === 200;
};

// DELETE request
const deleteUser = async (userId: string) => {
  await request({
    url: `https://api.example.com/users/${userId}`,
    method: 'DELETE',
    header: {
      'Authorization': 'Bearer token123'
    }
  });
};

Request Interceptors

Powerful interceptor system for modifying requests and responses globally across the application.

/**
 * Add request interceptor to modify requests before they are sent
 * @param interceptor - Interceptor function or object
 */
function addInterceptor(interceptor: Interceptor): void;

/**
 * Remove all registered interceptors
 */
function cleanInterceptors(): void;

interface Interceptor {
  /** Request interceptor function */
  request?: (config: RequestOption) => RequestOption | Promise<RequestOption>;
  /** Response interceptor function */
  response?: (response: RequestResult) => RequestResult | Promise<RequestResult>;
  /** Error interceptor function */
  responseError?: (error: any) => any | Promise<any>;
}

// Alternative function-based interceptor
type InterceptorFunction = (config: RequestOption) => RequestOption | Promise<RequestOption>;

File Download API

Full-featured file download functionality with progress tracking and binary data support.

/**
 * Download file from remote server to temporary local path
 * @param options - Download configuration options
 * @returns Promise resolving to download task with progress tracking
 */
function downloadFile(options: DownloadFileOption): Promise<DownloadFileResult> & DownloadTask;

interface DownloadFileOption {
  /** Target URL for file download (required) */
  url: string;
  /** HTTP headers object */
  header?: Record<string, string>;
  /** Include credentials for cross-origin requests */
  withCredentials?: boolean;
  /** Request timeout in milliseconds (default: 60000) */
  timeout?: number;
  /** Success callback function */
  success?: (result: DownloadFileResult) => void;
  /** Failure callback function */
  fail?: (error: any) => void;
  /** Completion callback function */
  complete?: (result: DownloadFileResult | any) => void;
}

interface DownloadFileResult {
  /** Temporary file path (blob URL) */
  tempFilePath: string;
  /** HTTP status code */
  statusCode: number;
  /** Error message (if download failed) */
  errMsg?: string;
}

interface DownloadTask {
  /** Abort the download operation */
  abort(): void;
  /** Monitor HTTP Response Header events */
  onHeadersReceived(callback: (res: { header: string }) => void): void;
  /** Remove HTTP Response Header event listener */
  offHeadersReceived(callback: (res: { header: string }) => void): void;
  /** Monitor download progress events */
  onProgressUpdate(callback: (res: DownloadProgressResult) => void): void;
  /** Remove download progress event listener */
  offProgressUpdate(callback: (res: DownloadProgressResult) => void): void;
}

interface DownloadProgressResult {
  /** Download progress percentage (0-100) */
  progress: number;
  /** Total bytes written so far */
  totalBytesWritten: number;
  /** Expected total bytes to write */
  totalBytesExpectedToWrite: number;
}

Usage Examples:

import { downloadFile } from "@tarojs/taro-h5";

// Basic file download
const downloadImage = async () => {
  try {
    const result = await downloadFile({
      url: 'https://example.com/image.jpg',
      header: {
        'Authorization': 'Bearer token123'
      }
    });
    
    console.log('Downloaded to:', result.tempFilePath);
    console.log('Status:', result.statusCode);
    
    // Use the temporary file path (blob URL)
    const img = document.createElement('img');
    img.src = result.tempFilePath;
    document.body.appendChild(img);
    
  } catch (error) {
    console.error('Download failed:', error);
  }
};

// Download with progress tracking
const downloadWithProgress = () => {
  const task = downloadFile({
    url: 'https://example.com/large-file.zip',
    success: (res) => {
      console.log('Download completed:', res.tempFilePath);
    },
    fail: (error) => {
      console.error('Download failed:', error);
    }
  });
  
  // Track download progress
  task.onProgressUpdate((res) => {
    console.log(`Progress: ${res.progress}%`);
    console.log(`Downloaded: ${res.totalBytesWritten} / ${res.totalBytesExpectedToWrite} bytes`);
    
    // Update UI progress bar
    updateProgressBar(res.progress);
  });
  
  // Handle headers received
  task.onHeadersReceived((res) => {
    console.log('Headers received:', res.header);
  });
  
  // Cancel download if needed
  setTimeout(() => {
    task.abort();
    console.log('Download cancelled');
  }, 10000); // Cancel after 10 seconds
};

File Upload API

Multipart form data upload functionality with progress tracking and metadata support.

/**
 * Upload local file to remote server using multipart/form-data
 * @param options - Upload configuration options
 * @returns Promise resolving to upload task with progress tracking
 */
function uploadFile(options: UploadFileOption): Promise<UploadFileResult> & UploadTask;

interface UploadFileOption {
  /** Target URL for file upload (required) */
  url: string;
  /** File path to upload (blob URL or File object) */
  filePath: string;
  /** Form field name for the file (required) */
  name: string;
  /** HTTP headers object */
  header?: Record<string, string>;
  /** Additional form data fields */
  formData?: Record<string, string>;
  /** Request timeout in milliseconds (default: 60000) */
  timeout?: number;
  /** Custom filename for the uploaded file */
  fileName?: string;
  /** Include credentials for cross-origin requests */
  withCredentials?: boolean;
  /** Success callback function */
  success?: (result: UploadFileResult) => void;
  /** Failure callback function */
  fail?: (error: any) => void;
  /** Completion callback function */
  complete?: (result: UploadFileResult | any) => void;
}

interface UploadFileResult {
  /** Server response data */
  data: string;
  /** HTTP status code */
  statusCode: number;
  /** Error message (if upload failed) */
  errMsg?: string;
}

interface UploadTask {
  /** Abort the upload operation */
  abort(): void;
  /** Monitor HTTP Response Header events */
  onHeadersReceived(callback: (res: { header: string }) => void): void;
  /** Remove HTTP Response Header event listener */
  offHeadersReceived(callback: (res: { header: string }) => void): void;
  /** Monitor upload progress events */
  onProgressUpdate(callback: (res: UploadProgressResult) => void): void;
  /** Remove upload progress event listener */
  offProgressUpdate(callback: (res: UploadProgressResult) => void): void;
}

interface UploadProgressResult {
  /** Upload progress percentage (0-100) */
  progress: number;
  /** Total bytes sent so far */
  totalBytesSent: number;
  /** Expected total bytes to send */
  totalBytesExpectedToSend: number;
}

Usage Examples:

import { uploadFile } from "@tarojs/taro-h5";

// Basic file upload
const uploadImage = async (fileBlob: Blob) => {
  try {
    // Create blob URL from file
    const filePath = URL.createObjectURL(fileBlob);
    
    const result = await uploadFile({
      url: 'https://api.example.com/upload',
      filePath: filePath,
      name: 'image',
      fileName: 'photo.jpg',
      header: {
        'Authorization': 'Bearer token123'
      },
      formData: {
        'userId': '12345',
        'category': 'profile'
      }
    });
    
    console.log('Upload completed');
    console.log('Server response:', result.data);
    console.log('Status:', result.statusCode);
    
    // Clean up blob URL
    URL.revokeObjectURL(filePath);
    
  } catch (error) {
    console.error('Upload failed:', error);
  }
};

// Upload with progress tracking
const uploadWithProgress = (fileInput: HTMLInputElement) => {
  const file = fileInput.files?.[0];
  if (!file) return;
  
  const filePath = URL.createObjectURL(file);
  
  const task = uploadFile({
    url: 'https://api.example.com/upload',
    filePath: filePath,
    name: 'file',
    fileName: file.name,
    formData: {
      'timestamp': Date.now().toString(),
      'fileSize': file.size.toString()
    },
    success: (res) => {
      console.log('Upload successful:', JSON.parse(res.data));
      URL.revokeObjectURL(filePath);
    },
    fail: (error) => {
      console.error('Upload failed:', error);
      URL.revokeObjectURL(filePath);
    }
  });
  
  // Track upload progress
  task.onProgressUpdate((res) => {
    console.log(`Upload progress: ${res.progress}%`);
    console.log(`Uploaded: ${res.totalBytesSent} / ${res.totalBytesExpectedToSend} bytes`);
    
    // Update UI progress
    const progressPercent = res.progress;
    updateUploadProgress(progressPercent);
  });
  
  // Handle response headers
  task.onHeadersReceived((res) => {
    console.log('Response headers received:', res.header);
  });
  
  // Cancel upload if needed
  const cancelButton = document.getElementById('cancel-upload');
  cancelButton?.addEventListener('click', () => {
    task.abort();
    console.log('Upload cancelled');
    URL.revokeObjectURL(filePath);
  });
};

// Multiple file upload
const uploadMultipleFiles = async (files: FileList) => {
  const uploadPromises = Array.from(files).map(async (file) => {
    const filePath = URL.createObjectURL(file);
    
    try {
      const result = await uploadFile({
        url: 'https://api.example.com/upload',
        filePath: filePath,
        name: 'files',
        fileName: file.name
      });
      
      URL.revokeObjectURL(filePath);
      return { success: true, fileName: file.name, result };
      
    } catch (error) {
      URL.revokeObjectURL(filePath);
      return { success: false, fileName: file.name, error };
    }
  });
  
  const results = await Promise.all(uploadPromises);
  
  results.forEach(result => {
    if (result.success) {
      console.log(`✓ ${result.fileName} uploaded successfully`);
    } else {
      console.error(`✗ ${result.fileName} failed:`, result.error);
    }
  });
};

WebSocket APIs

Real-time bidirectional communication support using WebSocket protocol with task-based management.

/**
 * Establish WebSocket connection to remote server
 * @param options - WebSocket connection options
 * @returns Promise resolving to SocketTask for connection management
 */
function connectSocket(options: ConnectSocketOption): Promise<SocketTask>;

interface ConnectSocketOption {
  /** WebSocket server URL (must use ws:// or wss://) */
  url: string;
  /** WebSocket sub-protocols array */
  protocols?: string[];
  /** Success callback function */
  success?: (res: { socketTaskId?: number }) => void;
  /** Failure callback function */
  fail?: (error: any) => void;
  /** Completion callback function */
  complete?: (res: any) => void;
}

interface SocketTask {
  /** Send data through WebSocket connection */
  send(options: SocketSendOption): Promise<void>;
  /** Close WebSocket connection */
  close(options?: SocketCloseOption): Promise<void>;
  /** Listen for connection open event */
  onOpen(callback: (res: any) => void): void;
  /** Remove connection open event listener */
  offOpen(callback: (res: any) => void): void;
  /** Listen for message received event */
  onMessage(callback: (res: SocketMessageResult) => void): void;
  /** Remove message received event listener */
  offMessage(callback: (res: SocketMessageResult) => void): void;
  /** Listen for connection error event */
  onError(callback: (res: any) => void): void;
  /** Remove connection error event listener */
  offError(callback: (res: any) => void): void;
  /** Listen for connection close event */
  onClose(callback: (res: SocketCloseResult) => void): void;
  /** Remove connection close event listener */
  offClose(callback: (res: SocketCloseResult) => void): void;
}

interface SocketSendOption {
  /** Data to send (string or ArrayBuffer) */
  data: string | ArrayBuffer;
  /** Success callback function */
  success?: () => void;
  /** Failure callback function */
  fail?: (error: any) => void;
  /** Completion callback function */
  complete?: () => void;
}

interface SocketCloseOption {
  /** Close code (default: 1000) */
  code?: number;
  /** Close reason */
  reason?: string;
  /** Success callback function */
  success?: () => void;
  /** Failure callback function */
  fail?: (error: any) => void;
  /** Completion callback function */
  complete?: () => void;
}

interface SocketMessageResult {
  /** Received message data */
  data: string | ArrayBuffer;
}

interface SocketCloseResult {
  /** Close code */
  code: number;
  /** Close reason */
  reason: string;
  /** Whether close was initiated by client */
  wasClean: boolean;
}

Usage Examples:

import { connectSocket } from "@tarojs/taro-h5";

// Basic WebSocket connection
const connectToWebSocket = async () => {
  try {
    const socketTask = await connectSocket({
      url: 'wss://api.example.com/websocket',
      protocols: ['chat', 'notifications']
    });
    
    // Handle connection opened
    socketTask.onOpen((res) => {
      console.log('WebSocket connected');
      
      // Send initial message
      socketTask.send({
        data: JSON.stringify({
          type: 'join',
          userId: '12345'
        })
      });
    });
    
    // Handle incoming messages
    socketTask.onMessage((res) => {
      const message = JSON.parse(res.data as string);
      console.log('Received message:', message);
      
      // Process different message types
      switch (message.type) {
        case 'chat':
          displayChatMessage(message.content);
          break;
        case 'notification':
          showNotification(message.title, message.body);
          break;
        default:
          console.log('Unknown message type:', message.type);
      }
    });
    
    // Handle connection errors
    socketTask.onError((error) => {
      console.error('WebSocket error:', error);
    });
    
    // Handle connection closed
    socketTask.onClose((res) => {
      console.log('WebSocket closed:', res.code, res.reason);
      
      // Attempt reconnection if not intentionally closed
      if (res.code !== 1000) {
        console.log('Attempting to reconnect...');
        setTimeout(connectToWebSocket, 3000);
      }
    });
    
    return socketTask;
    
  } catch (error) {
    console.error('Failed to connect WebSocket:', error);
  }
};

// Chat application example
class WebSocketChat {
  private socketTask: SocketTask | null = null;
  private reconnectAttempts = 0;
  private maxReconnectAttempts = 5;
  
  async connect(userId: string) {
    try {
      this.socketTask = await connectSocket({
        url: `wss://chat.example.com/ws?userId=${userId}`,
        success: () => {
          console.log('Chat connection initiated');
          this.reconnectAttempts = 0;
        },
        fail: (error) => {
          console.error('Chat connection failed:', error);
          this.handleReconnect();
        }
      });
      
      this.setupEventHandlers();
      
    } catch (error) {
      console.error('Failed to establish chat connection:', error);
      this.handleReconnect();
    }
  }
  
  private setupEventHandlers() {
    if (!this.socketTask) return;
    
    this.socketTask.onOpen(() => {
      console.log('Chat connection established');
      this.sendMessage({
        type: 'user_online',
        timestamp: Date.now()
      });
    });
    
    this.socketTask.onMessage((res) => {
      const message = JSON.parse(res.data as string);
      this.handleIncomingMessage(message);
    });
    
    this.socketTask.onError((error) => {
      console.error('Chat connection error:', error);
    });
    
    this.socketTask.onClose((res) => {
      console.log('Chat connection closed');
      if (res.code !== 1000) {
        this.handleReconnect();
      }
    });
  }
  
  sendChatMessage(text: string) {
    this.sendMessage({
      type: 'chat',
      text: text,
      timestamp: Date.now()
    });
  }
  
  sendTypingIndicator(isTyping: boolean) {
    this.sendMessage({
      type: 'typing',
      isTyping: isTyping
    });
  }
  
  private sendMessage(message: any) {
    if (!this.socketTask) {
      console.error('No active WebSocket connection');
      return;
    }
    
    this.socketTask.send({
      data: JSON.stringify(message),
      success: () => {
        console.log('Message sent successfully');
      },
      fail: (error) => {
        console.error('Failed to send message:', error);
      }
    });
  }
  
  private handleIncomingMessage(message: any) {
    switch (message.type) {
      case 'chat':
        this.displayChatMessage(message);
        break;
      case 'user_joined':
        this.showUserJoined(message.userId);
        break;
      case 'user_left':
        this.showUserLeft(message.userId);
        break;
      case 'typing':
        this.showTypingIndicator(message.userId, message.isTyping);
        break;
      default:
        console.log('Unknown message type:', message.type);
    }
  }
  
  private handleReconnect() {
    if (this.reconnectAttempts >= this.maxReconnectAttempts) {
      console.error('Max reconnection attempts reached');
      return;
    }
    
    this.reconnectAttempts++;
    const delay = Math.pow(2, this.reconnectAttempts) * 1000; // Exponential backoff
    
    console.log(`Reconnecting in ${delay}ms (attempt ${this.reconnectAttempts})`);
    
    setTimeout(() => {
      this.connect(this.getCurrentUserId());
    }, delay);
  }
  
  async disconnect() {
    if (!this.socketTask) return;
    
    try {
      await this.socketTask.close({
        code: 1000,
        reason: 'User disconnected'
      });
      
      console.log('Chat disconnected successfully');
      
    } catch (error) {
      console.error('Error disconnecting chat:', error);
    }
    
    this.socketTask = null;
  }
  
  // Placeholder methods for UI integration
  private displayChatMessage(message: any) {
    console.log(`${message.userId}: ${message.text}`);
  }
  
  private showUserJoined(userId: string) {
    console.log(`${userId} joined the chat`);
  }
  
  private showUserLeft(userId: string) {
    console.log(`${userId} left the chat`);
  }
  
  private showTypingIndicator(userId: string, isTyping: boolean) {
    console.log(`${userId} is ${isTyping ? 'typing' : 'not typing'}`);
  }
  
  private getCurrentUserId(): string {
    return 'current-user-id'; // Get from app state
  }
}

// Usage
const chat = new WebSocketChat();
await chat.connect('user123');

// Send messages
chat.sendChatMessage('Hello everyone!');
chat.sendTypingIndicator(true);

// Later disconnect
await chat.disconnect();

Usage Examples:

import { addInterceptor, cleanInterceptors, request } from "@tarojs/taro-h5";

// Add authentication interceptor
addInterceptor({
  request: (config) => {
    // Add auth token to all requests
    const token = getStorageSync('authToken');
    if (token) {
      config.header = {
        ...config.header,
        'Authorization': `Bearer ${token}`
      };
    }
    
    // Add request ID for tracking
    config.header['X-Request-ID'] = Date.now().toString();
    
    console.log('Outgoing request:', config.url);
    return config;
  },
  
  response: (response) => {
    // Log successful responses
    console.log(`Response ${response.statusCode}:`, response.data);
    
    // Handle global response processing
    if (response.data && response.data.code === 0) {
      // Extract data from wrapper
      response.data = response.data.data;
    }
    
    return response;
  },
  
  responseError: (error) => {
    // Handle global error scenarios
    console.error('Request failed:', error);
    
    // Handle authentication errors
    if (error.statusCode === 401) {
      // Redirect to login
      console.log('Authentication required, redirecting to login');
      // Clear invalid token
      removeStorageSync('authToken');
    }
    
    // Handle server errors
    if (error.statusCode >= 500) {
      showToast({
        title: 'Server error, please try again',
        icon: 'error'
      });
    }
    
    throw error;
  }
});

// Add base URL interceptor
addInterceptor({
  request: (config) => {
    // Add base URL if not already absolute
    if (!config.url.startsWith('http')) {
      const baseURL = getStorageSync('apiBaseURL') || 'https://api.example.com';
      config.url = `${baseURL}${config.url}`;
    }
    return config;
  }
});

// Add retry interceptor
let retryCount = 0;
const MAX_RETRIES = 3;

addInterceptor({
  responseError: async (error) => {
    if (retryCount < MAX_RETRIES && error.statusCode >= 500) {
      retryCount++;
      console.log(`Retrying request (${retryCount}/${MAX_RETRIES})`);
      
      // Wait before retry
      await new Promise(resolve => setTimeout(resolve, 1000 * retryCount));
      
      // Retry the original request
      return request(error.config);
    }
    
    retryCount = 0; // Reset on final failure
    throw error;
  }
});

// Remove all interceptors when needed
function resetInterceptors() {
  cleanInterceptors();
  console.log('All interceptors removed');
}

Advanced Request Patterns

Complex request scenarios and best practices for common use cases.

// File upload simulation (since actual file upload varies by implementation)
const uploadFile = async (file: File, uploadUrl: string) => {
  // Convert file to base64 for transmission
  const fileData = await new Promise<string>((resolve) => {
    const reader = new FileReader();
    reader.onload = () => resolve(reader.result as string);
    reader.readAsDataURL(file);
  });
  
  const response = await request({
    url: uploadUrl,
    method: 'POST',
    data: {
      filename: file.name,
      fileType: file.type,
      fileData: fileData,
      size: file.size
    },
    header: {
      'Content-Type': 'application/json'
    },
    timeout: 30000 // Extended timeout for uploads
  });
  
  return response.data;
};

// Batch requests with concurrency control
const batchRequests = async <T>(
  urls: string[], 
  concurrency: number = 3
): Promise<T[]> => {
  const results: T[] = [];
  
  for (let i = 0; i < urls.length; i += concurrency) {
    const batch = urls.slice(i, i + concurrency);
    const batchPromises = batch.map(url =>
      request({ url, method: 'GET' }).then(res => res.data)
    );
    
    const batchResults = await Promise.all(batchPromises);
    results.push(...batchResults);
  }
  
  return results;
};

// Request with timeout and retry
const requestWithRetry = async (
  options: RequestOption,
  maxRetries: number = 3,
  retryDelay: number = 1000
): Promise<RequestResult> => {
  let lastError: any;
  
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    try {
      return await request({
        ...options,
        timeout: options.timeout || 5000
      });
    } catch (error) {
      lastError = error;
      
      if (attempt < maxRetries) {
        console.log(`Request attempt ${attempt} failed, retrying in ${retryDelay}ms`);
        await new Promise(resolve => setTimeout(resolve, retryDelay));
        retryDelay *= 2; // Exponential backoff
      }
    }
  }
  
  throw lastError;
};

// Cached requests with TTL
const requestCache = new Map<string, { data: any, timestamp: number, ttl: number }>();

const cachedRequest = async (
  options: RequestOption,
  ttlMs: number = 300000 // 5 minutes default
): Promise<RequestResult> => {
  const cacheKey = `${options.method || 'GET'}:${options.url}:${JSON.stringify(options.data || {})}`;
  const cached = requestCache.get(cacheKey);
  
  if (cached && Date.now() - cached.timestamp < cached.ttl) {
    console.log('Returning cached response for:', options.url);
    return {
      data: cached.data,
      statusCode: 200,
      header: {},
      cookies: []
    };
  }
  
  const response = await request(options);
  
  // Cache successful responses
  if (response.statusCode >= 200 && response.statusCode < 300) {
    requestCache.set(cacheKey, {
      data: response.data,
      timestamp: Date.now(),
      ttl: ttlMs
    });
  }
  
  return response;
};

Error Handling

Comprehensive error handling patterns for network requests.

// Detailed error handling
const handleApiRequest = async (options: RequestOption) => {
  try {
    const response = await request(options);
    
    // Check for application-level errors
    if (response.data && response.data.error) {
      throw new Error(`API Error: ${response.data.error.message}`);
    }
    
    return response.data;
    
  } catch (error: any) {
    // Network or HTTP errors
    if (error.statusCode) {
      switch (error.statusCode) {
        case 400:
          throw new Error('Bad request - please check your data');
        case 401:
          throw new Error('Authentication required');
        case 403:
          throw new Error('Access forbidden');
        case 404:
          throw new Error('Resource not found');
        case 429:
          throw new Error('Too many requests - please wait');
        case 500:
          throw new Error('Server error - please try again later');
        default:
          throw new Error(`HTTP ${error.statusCode}: ${error.errMsg || 'Unknown error'}`);
      }
    }
    
    // Network connectivity errors
    if (error.message?.includes('timeout')) {
      throw new Error('Request timeout - please check your connection');
    }
    
    if (error.message?.includes('network')) {
      throw new Error('Network error - please check your connection');
    }
    
    // Re-throw unknown errors
    throw error;
  }
};

// Usage with proper error handling
async function fetchUserProfile(userId: string) {
  try {
    const profile = await handleApiRequest({
      url: `/api/users/${userId}`,
      method: 'GET'
    });
    
    return profile;
    
  } catch (error) {
    console.error('Failed to fetch user profile:', error.message);
    
    // Show user-friendly error message
    showToast({
      title: error.message || 'Failed to load profile',
      icon: 'error'
    });
    
    // Return fallback data or re-throw
    return null;
  }
}

Callback Pattern Support

Traditional callback pattern support alongside Promise-based usage.

// Using callbacks instead of promises
request({
  url: 'https://api.example.com/data',
  method: 'GET',
  success: (response) => {
    console.log('Success:', response.data);
    console.log('Status:', response.statusCode);
  },
  fail: (error) => {
    console.error('Request failed:', error);
  },
  complete: (result) => {
    console.log('Request completed');
    // Called regardless of success or failure
  }
});

// Mixed usage - callbacks with promise handling
const response = await request({
  url: 'https://api.example.com/data',
  method: 'POST',
  data: { message: 'Hello' },
  success: (res) => {
    console.log('Callback success:', res.statusCode);
  },
  fail: (err) => {
    console.log('Callback failure:', err);
  }
});

console.log('Promise result:', response.data);

Types

type HTTPMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'HEAD' | 'OPTIONS';
type DataType = 'json' | 'text' | 'base64';
type ResponseType = 'text' | 'json' | 'arraybuffer';

interface NetworkError extends Error {
  statusCode?: number;
  errMsg?: string;
  config?: RequestOption;
}

Install with Tessl CLI

npx tessl i tessl/npm-tarojs--taro-h5

docs

canvas.md

core-framework.md

device.md

dom-query.md

index.md

location.md

media.md

navigation.md

network.md

storage.md

system-info.md

ui-interactions.md

tile.json