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

Flutter日程应用从Google Sheets恢复备份数据时JSON解析失败求助

问题排查与修复方案

核心问题

恢复数据时出现Expected JSON but got text/html错误,根源在于两个关键点:

  1. 前端GET请求参数传递方式错误:你通过请求头传递acc和tbl,但Google Apps Script的doGet方法仅解析URL查询参数,无法识别请求头中的参数,导致后端返回HTML错误页面。
  2. 后端(Google Apps Script)未正确返回JSON格式数据:即使参数传递正确,若后端未明确设置返回MIME类型为JSON,也会导致Content-Type不符合预期。

修复步骤

1. 修改前端GET请求参数传递方式

将acc和tbl从请求头移到URL查询参数中,修改BackendHelper的getData方法:

import 'package:http/http.dart' as http;
import 'package:logger/logger.dart';

class BackendHelper {
  static const String _server = "script.google.com";
  static Logger logger = Logger();

  // 保留sendData方法不变
  static Future<int> sendData(String jsonData) async {
    var client = http.Client();
    int code = -1;
    try {
      var response = await client.post(
        Uri.https(_server, "macros/s/AKfycby3g-CRk53h4Rr07VWxJr4d6CYm33_-cft8nOeIlwAuOFwAjzMz6jDamo_HHxpFtTz-/exec"),
        body: {'acc': '2', 'tbl': 'Contacts', 'data': jsonData},
      );
      code = response.statusCode;
      logger.i(response.statusCode);
    } finally {
      client.close();
    }
    return code;
  }

  static Future<String> getData() async {
    var client = http.Client();
    String responseBody = '';
    try {
      var response = await client.get(
        Uri.https(
          _server,
          "macros/s/AKfycby3g-CRk53h4Rr07VWxJr4d6CYm33_-cft8nOeIlwAuOFwAjzMz6jDamo_HHxpFtTz-/exec",
          {'acc': '1', 'tbl': 'Contacts'}, // 参数移至查询参数中
        ),
      );
      if (response.statusCode == 200) {
        if (response.headers['content-type']?.contains('application/json') == true) {
          responseBody = response.body;
          logger.i('Data retrieved successfully');
        } else {
          logger.e('Expected JSON but got ${response.headers['content-type']}');
          // 打印原始响应内容,方便排查后端问题
          logger.d('Raw response body: ${response.body}');
          responseBody = 'Invalid response: Expected JSON';
        }
      } else {
        logger.e('Failed to retrieve data. Status code: ${response.statusCode}');
        logger.d('Raw response body: ${response.body}');
        responseBody = 'Error: ${response.statusCode}';
      }
    } finally {
      client.close();
    }
    return responseBody;
  }
}

2. 确保Google Apps Script后端正确返回JSON

以下是标准的doGet实现,确保它能处理查询参数并返回正确的JSON:

function doGet(e) {
  // 从查询参数中获取acc和tbl
  const acc = e.parameter.acc;
  const tbl = e.parameter.tbl;

  // 处理获取联系人的请求
  if (acc === '1' && tbl === 'Contacts') {
    try {
      // 获取对应工作表数据
      const spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
      const sheet = spreadsheet.getSheetByName('Contacts');
      if (!sheet) {
        throw new Error('Sheet "Contacts" not found');
      }

      // 转换表头+数据为JSON格式(跳过第一行表头)
      const [headers, ...rows] = sheet.getDataRange().getValues();
      const contacts = rows.map(row => {
        const contact = {};
        headers.forEach((header, index) => {
          contact[header] = row[index];
        });
        return contact;
      });

      // 返回JSON数据,明确设置MIME类型
      return ContentService.createTextOutput(JSON.stringify(contacts))
        .setMimeType(ContentService.MimeType.JSON);
    } catch (error) {
      // 错误时返回JSON格式的错误信息
      return ContentService.createTextOutput(JSON.stringify({error: error.message}))
        .setMimeType(ContentService.MimeType.JSON);
    }
  } else {
    // 无效请求返回JSON错误
    return ContentService.createTextOutput(JSON.stringify({error: 'Invalid request parameters'}))
      .setMimeType(ContentService.MimeType.JSON);
  }
}

3. 额外排查步骤

  • 直接测试后端接口:在浏览器中访问以下URL,查看返回内容是否为JSON:
    https://script.google.com/macros/s/AKfycby3g-CRk53h4Rr07VWxJr4d6CYm33_-cft8nOeIlwAuOFwAjzMz6jDamo_HHxpFtTz-/exec?acc=1&tbl=Contacts
    
    如果返回HTML,说明后端逻辑存在问题(比如权限未设置、工作表名称错误等);如果返回JSON,再检查前端请求。
  • 检查GAS权限:确保Google Apps Script已部署为“任何人,甚至匿名”可访问(部署时设置权限),否则前端请求会被拦截返回权限错误的HTML。

验证修复

修改完成后重新测试恢复功能:

  1. 后端返回的Content-Type会变为application/json
  2. 前端能正确解析JSON数据并写入本地数据库
  3. 恢复成功后会显示对应的SnackBar提示

内容的提问来源于stack exchange,提问作者SERGIO ANDRES VALDERRAMA VELEZ

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 03:35:55