繁体   English   中英

将 object 发布到 Google Cloud Storage 不会替换 ${filename} 变量

Posting object to Google Cloud Storage doesn't replace ${filename} variable

提示:本站收集StackOverFlow近2千万问答,支持中英文搜索,鼠标放在语句上弹窗显示对应的参考中文或英文, 本站还提供   中文繁体   英文版本   中英对照 版本,有任何建议请联系yoyou2525@163.com。

如此处所述https://cloud.google.com/storage/docs/xml-api/post-object

从浏览器上传文件到 GCS 时(使用签名请求),我可以使用${filename}作为密钥的一部分。

这很好,因为它与 S3 使用的变量完全相同。 但是 - 一个问题。 当我上传时,它实际上并没有用文件名替换${filename} 这在 S3 上完美运行,但使用 GCS,我确实得到$%7Bfilename%7D作为响应中的键 - 显然它没有用正确的值替换它。

我正在构建这样的请求:

export function uploadVideo(video) {
  return new Promise((resolve, reject) => {
    if (!video) {
      resolve(null);
      return;
    }
    // this fetches a presigned post object from the server:
    request.get('/presigned_post')
      .query({format: 'json'})
      .end((err, response)=> {
        if (!err && response.ok) {
          request
            .post(`https://${response.body.url.host}/`)
            .field(response.body.fields)
            .field('Content-Type', image.type)
            .attach('file', image, image.name)
            .end((err, response) => {
              if (err) {
                console.log("Error uploading image: ", err);
                reject(err);
              } else {
                resolve({
                  location: response.text.match('<Location>' + '(.*?)' + '</Location>')[1],
                  bucket: response.text.match('<Bucket>' + '(.*?)' + '</Bucket>')[1],
                  key: response.text.match('<Key>' + '(.*?)' + '</Key>')[1],
                  checksum: response.text.match('<ETag>"' + '(.*?)' + '"</ETag>')[1]
                });
              }
            });
        }
      });
  });
}

关键是some_folder/${filename} ,这包含在 google 的表单数据中(在response.fields中)。

您可以看到使用.attach('file', image, image.name)提供文件名。 正在正确上传,只是没有替换${filename}变量。

编辑

我已经进一步缩小了这个问题的范围。 我们查询 S3 和 GCS 以获取预签名帖子中的字段。 使用 S3,如果我给出${filename}的键,那么我会在字段中得到准确的返回值:

  def presigned_post(bucket_name:, key:, **opts)
    response = s3_resource.
      bucket(bucket_name).
      presigned_post(key: key, content_type_starts_with: '', **opts)

    {
      fields: response.fields,
      url:    { host: URI.parse(response.url).host }
    }
  end

此处的字段将包含"key"=>"${filename}"

但是在 GCS 的情况下,以下代码在字段中返回:key=>"$%7Bfilename%7D"

# https://cloud.google.com/storage/docs/xml-api/post-object#usage_and_examples
# https://www.rubydoc.info/gems/google-cloud-storage/1.0.1/Google/Cloud/Storage/Bucket:post_object
def presigned_post(bucket_name:, key:, acl:, success_action_status:, expiration: nil)
  expiration ||= (Time.now + 1.hour).iso8601

  policy = {
    expiration: expiration,
    conditions: [
      ["starts-with", "$key", "" ],
      ["starts-with", "$Content-Type", "" ],
      { acl: acl },
      { success_action_status: success_action_status }
    ]
  }

  post_obj = get_bucket!(bucket_name).post_object(key, policy: policy)

  url_obj = { host: URI.parse(post_obj.url).host }

  # Have to manually merge in these fields
  fields = post_obj.fields.merge(
    acl: acl,
    success_action_status: success_action_status
  )

  return { fields: fields, url: url_obj }
end

如果我手动更改 GCS 请求字段中的密钥,那么它可以工作。 这真的是我应该做的吗?

2 个回复

此问题的修复已在google-cloud-storage v1.24.0中发布。

发现问题是由以下原因引起的:

      def ext_path
        URI.escape "/#{@bucket}/#{@path}"
      end

在 google-cloud-ruby-gem 的lib/google/cloud/storage/file.rb中。

这由同一个文件中的def post_object调用。

我将在他们的 Github 页面上提出一个问题

1 如何模拟 google.cloud.storage.blob.Blob 对象列表?

我有一个函数,它接受一堆 google.cloud.storage.blob.Blob 对象列表,以按我想要单元测试的创建日期进行解析。 我该如何去嘲笑它? 我考虑过打补丁,但我意识到这更多是针对正在测试的函数内的调用。 我如何模拟这些 blob 的输入? 这是我要测试的功能: 其中对象属于 & ...

2 Apache Beam无法正确接收来自google-cloud-storage的发布/订阅消息

我已经在这个问题上苦苦挣扎了一段时间,却找不到解决方法。 我正在建立一个从公共Google云存储桶中获取数据并对其进行一些转换的管道。 我现在正努力解决的问题是,每当文件上传到云中时,apache Beam就会接收发布/子消息。 对此有一个公共主题,称为projects/gcp-public-dat ...

4 如何从@google-cloud/storage 读取文件?

我正在从我的存储桶中检索一个文件。 我得到文件并想阅读它的内容,但我不想将它下载到我的本地项目,我只想阅读内容,获取数据并用它做其他操作。 我的代码: readFileData 未定义。 这可能吗? 我发现的每个示例都涉及我下载文件。 ...

7 如何从 google-cloud-storage 中自动删除旧版本

每次更新站点相关数据时,我都会将文件 html 文件写入 GCS。 该网站维护版本,因此可以选择手动还原。 我需要删除早于 2 天的以前(不是最后一个)版本的文件。 GCS 配置中有没有一种方法可以在创建下一个版本时设置以前版本的到期时间? 还是基于计划删除的下一个版本的创建日期? 如果没有,从 ...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2022 STACKOOM.COM