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

如何向GAS函数传递数据?名片上传Web应用报错排查

问题描述

使用Google Apps Script开发一款小型Web应用,功能为上传名片图片至Google Drive,通过ChatGPT提取图片信息后保存到Google Sheets。目前Index.html页面可选择并尝试上传图片,但出现错误Uncaught at uploadImageToServer (Code:34)。通过console.log验证确认Data URL已生成,但该数据无法传递至GAS函数uploadImageToServer(),执行日志显示接收到的dataUrl为undefined。

HTML代码

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <style>
      #status {
        margin-top: 10px;
        font-weight: bold;
      }
    </style>
  </head>
  <body>
    <form id="uploadForm">
      <input type="file" id="fileInput" accept="image/*">
      <input type="button" value="Upload" onclick="uploadImage()">
    </form>
    <pre id="result"></pre>
    <div id="status"></div>
    <script>
      function uploadImage() {
        const fileInput = document.getElementById('fileInput');
        const file = fileInput.files[0];
        const statusDiv = document.getElementById('status');

        if (!file) {
          alert("Please select a file before uploading.");
          return;
        }

        statusDiv.textContent = "Uploading image, please wait...";

        const reader = new FileReader();

        reader.onload = function(e) {
          const dataUrl = e.target.result;
          console.log("Data URL:", dataUrl);

          if (dataUrl) {
            google.script.run.withSuccessHandler(function(response) {
              document.getElementById('result').textContent = JSON.stringify(response, null, 2);            
            }).uploadImageToServer(dataUrl);

            statusDiv.textContent = "Image uploaded successfully. Processing...";
          } else {
            console.error("Failed to generate Data URL.");
            statusDiv.textContent = "Error uploading image.";
          }
        };

        reader.onerror = function(error) {
          console.error("Error reading file:", error);
          statusDiv.textContent = "Error uploading image.";
        };

        reader.readAsDataURL(file);
    </script>
  </body>
</html>

Code.gs脚本

function doGet() {
  return HtmlService.createHtmlOutputFromFile('Index');
}

function uploadImageToServer(dataUrl) {
  Logger.log("Upload function started");

  try {
    Logger.log("Received dataUrl: " + dataUrl);

    if (!dataUrl) {
      throw new Error("No dataUrl received");
    }

    const matches = dataUrl.match(/^data:(.+);base64,(.*)$/);
    if (!matches || matches.length !== 3) {
      throw new Error('Could not parse the data URL.');
    }

    const contentType = matches[1];
    const data = matches[2];
    const blob = Utilities.newBlob(Utilities.base64Decode(data), contentType, "uploaded_image");

    const folder = DriveApp.getFolderById('xxx');
    const file = folder.createFile(blob);
    Logger.log("Image uploaded to Google Drive");

    const imageUrl = file.getUrl();
    Logger.log("Image URL: " + imageUrl);

    // 调用Google Cloud Vision API
    const apiKey = 'xxx';
    const visionUrl = `https://vision.googleapis.com/v1/images:annotate?key=${apiKey}`;
    const image = UrlFetchApp.fetch(imageUrl).getBlob().getBytes();
    const encodedImage = Utilities.base64Encode(image);
    Logger.log("已为Vision API编码图片");

    const visionPayload = {
      requests: [
        {
          image: {
            content: encodedImage
          },
          features: [
            {
              type: "TEXT_DETECTION"
            }
          ]
        }
      ]
    };

    const visionOptions = {
      method: "post",
      contentType: "application/json",
      payload: JSON.stringify(visionPayload)
    };

    const visionResponse = UrlFetchApp.fetch(visionUrl, visionOptions);
    Logger.log("已收到Vision API响应");

    const visionData = JSON.parse(visionResponse.getContentText());
    Logger.log("已解析Vision API数据: " + JSON.stringify(visionData));

    if (!visionData.responses || !visionData.responses[0] || !visionData.responses[0].fullTextAnnotation) {
      throw new Error("Vision API未识别到文本");
    }

    const text = visionData.responses[0].fullTextAnnotation.text;
    Logger.log("提取到的文本: " + text);

    // 调用OpenAI API
    const openaiApiKey = 'xxx';
    const openaiUrl = 'https://api.openai.com/v1/engines/davinci/completions';
    const prompt = `从以下名片文本中提取信息:\n\n${text}\n\n信息需以JSON格式输出,包含键'Company', 'Name', 'Title', 'Phone', 'Website', 'Email', 'Address'。`;

    const openaiPayload = {
      prompt: prompt,
      max_tokens: 150,
      n: 1,
      stop: null,
      temperature: 0.5
    };

    const openaiOptions = {
      method: 'post',
      contentType: 'application/json',
      headers: {
        'Authorization': `Bearer ${openaiApiKey}`
      },
      payload: JSON.stringify(openaiPayload)
    };

    const openaiResponse = UrlFetchApp.fetch(openaiUrl, openaiOptions);
    Logger.log("已收到OpenAI API响应");

    const openaiData = JSON.parse(openaiResponse.getContentText());
    Logger.log("已解析OpenAI API数据: " + JSON.stringify(openaiData));

    const jsonResponse = openaiData.choices[0].text.trim();
    Logger.log("已解析OpenAI响应内容: " + jsonResponse);

    const parsedData = JSON.parse(jsonResponse);

    if (!parsedData.Company || !parsedData.Name) {
      throw new Error("解析的数据不完整");
    }
    
    const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
    const row = [parsedData.Company, parsedData.Name, parsedData.Title, parsedData.Phone, parsedData.Website, parsedData.Email, parsedData.Address];
    sheet.appendRow(row);
    Logger.log("数据已添加至Google Sheet");

    return parsedData;
  } catch (error) {
    Logger.log("错误: " + error.message);
    throw error;
  }
}

执行日志

时间类型内容
12:37:37 AM通知执行已启动
12:37:06 AM信息上传函数已启动
12:37:06 AM信息接收到的dataUrl: undefined
12:37:06 AM信息错误: 未接收到dataUrl
12:37:37 AM错误错误: 未接收到dataUrl
uploadImageToServer @ Code.gs:12

相关资源

Google表格、脚本项目、测试Web应用


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 16:05:55