【问题标题】:UrlFetchApp upload file multipart/form-data in Google Apps ScriptUrlFetchApp 在 Google Apps 脚本中上传文件 multipart/form-data
【发布时间】:2014-06-21 09:41:44
【问题描述】:

我需要将文件上传到第三方服务。这些文件是在 Google Drive 上创建的,我得到了它的 blob 数据。

我想创建一个多部分请求,当我执行 UrlFetchApp 发布时,它现在看起来像这样。

这是作为字符串的有效负载。我有一些生成有效负载的代码。正确格式化不是问题,这是它应该的格式。

-----------------0.13accb4c42d338
Content-Disposition: form-data; name="source"; filename="Zzapps.jpg"
Content-Type: application/octet-stream

[[[IMAGE DATA HERE -- OMITTED FOR BREVITY]]]

-----------------0.13accb4c42d338
Content-Disposition: form-data; name="filename"

Zzapps.jpg
-----------------0.13accb4c42d338--

这是执行 UrlFetchApp 命令的代码。

var authHeaders = {
   Authorization: 'OAuth2 '+access_token
}
 var params = {
    accept: "application/json",
    method: 'POST',
    payload: payload,
    contentType: 'multipart/form-data; boundary='+boundaryKey,
    headers: authHeaders,
    ContentLength: payload.length,
    muteHttpExceptions: true
}

var resx = UrlFetchApp.fetch(url, params);

接收方给出错误(缺少来源)。我不确定我的 multipart-post 一开始是否还可以,我没有找到任何测试 URL 来检查我是否正确上传。

如何以正确的方式将 blob 数据作为分段上传发送? 现在我使用 blob.getDataAsString()

【问题讨论】:

  • 在这种情况下,我从最简单的硬编码代码开始,我可以开始工作,然后从那里开始。尝试先做一些简单的工作。你看过执行记录以寻找线索吗?您是否使用 Logger.log() 来检查值?您的 params 对象是否被解析为对象?如果你使用 Logger.log('params: ' + params);你应该看到 [object:Object] 作为 params 的值。
  • 是的。我正在尝试发送一个有效的硬编码代码。我看不出能做到这一点。我希望多部分代码是 params.payload 参数中的字符串?
  • 我知道这可能有点太晚了,但在这篇文章中——ctrlq.org/code/20096-upload-files-multipart-post——这家伙成功了。
  • 这些信息对您的情况有用吗? github.com/tanaikech/FetchApp

标签: google-apps-script multipartform-data


【解决方案1】:

如果您自己构建有效负载字符串,您希望执行 blob.getBytes(),而不是 blob.getDataAsString()。

不过,还有一种更简单的方法。您无需自己构建有效负载字符串,只需将 javascript 对象设置为有效负载,UrlFetchApp 将自动生成适当的有效负载字符串,选择正确的内容类型、边界和大多数其他选项。只需使用 HTML 表单输入字段的“名称”属性作为对象键。对于文件,使用 blob 作为键的值。

function sendReportToSteve() {
  var url = "https://example.com/stevedore.html";
  var form = {
    date : new Date(),
    subject : "Happy birthday!",
    comment : "quakehashprismkeepkick",
    attachment1 : DriveApp.getFileById("sH1proy0lradArgravha9ikE").getBlob(),
    attachment2 : DriveApp.getFileById("traCetRacErI3hplVnkFax").getBlob()
  };
  uploadFile(url,form);
}

function uploadFile(url,form) {
  var options = {
    method : "POST",
    payload : form
  };
  var request = UrlFetchApp.getRequest(url,options);   // (OPTIONAL) generate the request so you
  console.info("Request payload: " + request.payload); // can examine it (useful for debugging)
  var response = UrlFetchApp.fetch(url,options);
  console.info("Response body: " + response.getContentText());
}

【讨论】:

  • 就我而言,我没有任何 HTML 表单的输入字段。我正在尝试以以下格式发布电子邮件元数据和电子邮件 rawContent。 {meta: {id, subject, date}, content: rawContent }。我怎样才能通过上述方法实现这一目标?
  • @V.i.K.i 我认为 UrlFetchApp 只能发出 HTTP 请求。据我了解,电子邮件是使用 SMTP 协议发送的,而不是 HTTP 协议。而不是 UrlFetchApp,请尝试 MailApp
  • 对不起,我之前的评论并不清楚。我不是想发送邮件。我正在尝试使用上述格式的有效负载向第 3 方 API 发出 HTTP POST 请求。我看到没有为此正确设置内容类型。现在,我必须退回到ctrlq.org/code/20096-upload-files-multipart-post 定义的方法。我想知道我们是否可以通过使用您的方法来避免这种情况。
  • @V.i.K.i 我认为 UrlFetchApp 只能处理一个“级别”的对象。对于子对象,您需要将其编码为 API 所期望的字符串(JSON、XML 等)。例如,您可以尝试var options = {method : "POST", payload : {meta : JSON.stringify({id : 5, subject : "foo", date : "2018-10-05"}), content : rawContent} }。您可能希望将blob 用于rawContent。 UrlFetchApp 不知道如何处理任意字节数组。
猜你喜欢
  • 1970-01-01
  • 2011-11-26
  • 1970-01-01
  • 1970-01-01
  • 2015-10-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多