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

Flutter实现FormData格式POST请求及图片上传问题(附JS示例)

Flutter实现FormData图片上传(对应你的JS逻辑)

Got it, let's walk through how to replicate your JavaScript FormData image upload functionality in Flutter. We'll use the http package (Flutter's go-to for HTTP requests) to handle multipart/form-data, mirror your hostname-based URL logic, and handle credentials just like xhr.withCredentials = true.

Step 1: Add the http dependency

First, make sure you have the http package in your pubspec.yaml:

dependencies:
  flutter:
    sdk: flutter
  http: ^1.1.0 # Use the latest version available

Run flutter pub get to install it.

Step 2: Replicate the hostname-based URL logic

In your JS code, you dynamically build the upload URL based on the current hostname. For Flutter web, you can grab the current hostname using dart:html; for mobile, you might use app-configured constants or pass the hostname as a parameter. Here's the mirrored logic:

import 'dart:html' as html; // Only for web targets

String buildUploadUrl(String uploadpoint) {
  final hostname = html.window.location.hostname;
  final protocol = html.window.location.protocol;

  if (hostname == "localhost") {
    return "http://localhost:9999/$uploadpoint";
  } else if (hostname == "www.aladin.finance") {
    return "$protocol//uploadfile.aladin.finance/$uploadpoint";
  } else {
    return "$protocol//uploadfile.$hostname/$uploadpoint";
  }
}

Note: For mobile apps, replace the hostname/protocol retrieval with your app's environment config (e.g., from a constants file or .env setup).

Step 3: Build the MultipartRequest (equivalent to FormData)

Flutter's MultipartRequest is the direct stand-in for JavaScript's FormData. We'll add your parameters (session, fileindex) and the image file to it. The code below supports both web and mobile file sources:

import 'package:http/http.dart' as http;
import 'dart:io'; // For mobile File
import 'dart:html' as html; // For web File
import 'package:http_parser/http_parser.dart'; // For MediaType

Future<void> uploadImage({
  required dynamic imageFile, // html.File for web, File for mobile
  required String sessionId,
  required int fileListIndex,
  required String uploadpoint,
}) async {
  // Build the target upload URL
  final url = buildUploadUrl(uploadpoint);

  // Initialize multipart request
  final request = http.MultipartRequest('POST', Uri.parse(url));

  // Add text parameters (matches formData.append)
  request.fields['session'] = sessionId;
  request.fields['fileindex'] = fileListIndex.toString();

  // Add the image file to the request
  if (imageFile is html.File) {
    // Handle web file: convert html.File to bytes for MultipartFile
    final reader = html.FileReader();
    await reader.readAsArrayBuffer(imageFile);
    final bytes = reader.result as List<int>;
    request.files.add(http.MultipartFile.fromBytes(
      'file',
      bytes,
      filename: imageFile.name,
      contentType: MediaType.parse(imageFile.type),
    ));
  } else if (imageFile is File) {
    // Handle mobile file: add directly from device path
    request.files.add(await http.MultipartFile.fromPath(
      'file',
      imageFile.path,
      filename: imageFile.path.split('/').last,
    ));
  }

  // Handle credentials (equivalent to xhr.withCredentials = true)
  // For web: Ensure cross-origin requests allow credentials (server must also set Access-Control-Allow-Credentials: true)
  request.headers['Access-Control-Allow-Credentials'] = 'true';
  // For mobile: To persist cookies across requests, use a package like `cookie_jar` with a custom http.Client
  // Example:
  // final cookieJar = CookieJar();
  // final client = http.Client();
  // client.interceptors.add(CookieManager(cookieJar));
  // final response = await client.send(request);

  // Send the request and handle response
  try {
    final response = await request.send();
    if (response.statusCode == 200) {
      print('Upload successful!');
      final responseBody = await response.stream.bytesToString();
      print('Server response: $responseBody');
      // Add your success handling logic here
    } else {
      print('Upload failed with status code: ${response.statusCode}');
      // Add error handling logic here
    }
  } catch (e) {
    print('Upload error: $e');
  }
}

Key Details to Match Your JS Logic:

  • FormData Equivalent: request.fields handles text parameters, while request.files manages file uploads, just like formData.append in JS.
  • WithCredentials: On web, setting Access-Control-Allow-Credentials in headers ensures cookies are sent with cross-origin requests (your server must also allow this). On mobile, use a cookie management package like cookie_jar to persist session cookies across requests.
  • Dynamic URL: The buildUploadUrl function mirrors your JS logic for targeting different upload endpoints based on hostname.

内容的提问来源于stack exchange,提问作者Khôi Trần Quang

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:02:08