You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从jQuery迁移到Flutter/Dart:$.Ajax代码转换求助

Hey there! I see you're new to Flutter/Dart and trying to convert your jQuery callAjax function over—let's break this down step by step. It's totally normal to struggle finding clear examples of network calls when you're focused on widget tutorials, so I'll walk you through recreating that functionality properly in Dart.

First, let's recap what your original jQuery function does:

  • Supports both asynchronous and synchronous requests (though synchronous is not recommended in Flutter)
  • Handles optional params and callback arguments
  • Converts the URL to lowercase and appends params
  • Sets Content-Type: application/json and skips data processing
  • Calls the callback with data on success, or null on error; returns data directly for synchronous calls

Here's the complete converted CallAjax class with explanations:

import 'package:flutter/material.dart';
import 'dart:convert';
import 'package:http/http.dart' as http;

class CallAjax {
  final String method;
  final String url;
  final String? params; // Mark as nullable since it's optional
  final Function(dynamic)? callback; // Nullable callback for sync cases

  CallAjax(this.method, this.url, [this.params, this.callback]); // Use optional positional args for cleaner calls

  // Async execution (RECOMMENDED for Flutter)
  Future<void> execute() async {
    // Handle default params value (matches JS's params === undefined check)
    final processedParams = params ?? '';
    final ajaxUrl = '${url.toLowerCase()}$processedParams';

    try {
      late http.Response response;

      // Match HTTP method from input
      switch (method.toUpperCase()) {
        case 'GET':
          response = await http.get(
            Uri.parse(ajaxUrl),
            headers: {'Content-Type': 'application/json'},
          );
          break;
        case 'POST':
          // Match JS's empty data: {}
          response = await http.post(
            Uri.parse(ajaxUrl),
            headers: {'Content-Type': 'application/json'},
            body: jsonEncode({}),
          );
          break;
        // Add PUT/DELETE cases here if needed
        default:
          throw Exception('Unsupported HTTP method: $method');
      }

      // Handle successful response
      if (response.statusCode >= 200 && response.statusCode < 300) {
        final jsonData = jsonDecode(response.body);
        callback?.call(jsonData); // Call callback if it exists
      } else {
        // Handle HTTP errors (matches JS's error callback)
        _showError('Internal Server Error: ${response.statusCode} ($ajaxUrl)');
        callback?.call(null);
      }
    } catch (e) {
      // Handle network errors (no internet, timeouts, etc.)
      _showError('Request failed: ${e.toString()}');
      callback?.call(null);
    }
  }

  // Sync execution (NOT RECOMMENDED for Flutter - blocks UI!)
  dynamic executeSync() {
    final processedParams = params ?? '';
    final ajaxUrl = '${url.toLowerCase()}$processedParams';
    dynamic result;

    try {
      late http.Response response;

      switch (method.toUpperCase()) {
        case 'GET':
          response = http.getSync(
            Uri.parse(ajaxUrl),
            headers: {'Content-Type': 'application/json'},
          );
          break;
        case 'POST':
          response = http.postSync(
            Uri.parse(ajaxUrl),
            headers: {'Content-Type': 'application/json'},
            body: jsonEncode({}),
          );
          break;
        default:
          throw Exception('Unsupported HTTP method: $method');
      }

      if (response.statusCode >= 200 && response.statusCode < 300) {
        result = jsonDecode(response.body);
      } else {
        _showError('Internal Server Error: ${response.statusCode} ($ajaxUrl)');
        result = null;
      }
    } catch (e) {
      _showError('Request failed: ${e.toString()}');
      result = null;
    }

    return result;
  }

  // Helper to show errors (replace with SnackBar/Dialog in a real app)
  void _showError(String message) {
    print(message);
    // For UI-level errors in a widget, use this instead:
    // if (context != null) {
    //   ScaffoldMessenger.of(context).showSnackBar(
    //     SnackBar(content: Text(message)),
    //   );
    // }
  }
}

Key Differences & Notes:

  1. Async First: Flutter heavily discourages synchronous network calls because they block the UI thread (causing freezes). Use execute() for all production code.
  2. Optional Arguments: I changed the constructor to use optional positional args ([this.params, this.callback]) so you can call it like CallAjax('GET', 'https://api.com') without passing null for missing params/callback.
  3. Error Handling: Dart uses try/catch for exceptions (like network failures), which replaces jQuery's error callback.
  4. JSON Handling: We use jsonEncode/jsonDecode from dart:convert to work with JSON data, matching jQuery's contentType: 'application/json'.

How to Use It:

// Async example (recommended)
CallAjax('GET', 'https://your-api-url.com/data', '?user=123', (data) {
  if (data != null) {
    print('Got data: $data');
    // Update your UI here with setState() or a state management solution
  } else {
    print('Request failed');
  }
}).execute();

// Sync example (only use this in non-UI code, like background isolates)
// final syncResult = CallAjax('POST', 'https://your-api-url.com/submit', '', null).executeSync();
// print('Sync result: $syncResult');

Quick Setup Tips for Newbies:

  • Add the http package to your pubspec.yaml:
    dependencies:
      flutter:
        sdk: flutter
      http: ^0.13.5 # Use the latest version
    
  • Run flutter pub get to install the package.
  • For Android, add internet permission to android/app/src/main/AndroidManifest.xml:
    <uses-permission android:name="android.permission.INTERNET"/>
    

内容的提问来源于stack exchange,提问作者Mythar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:35:20