【问题标题】:Uploading image to Firebase Storage via POST request通过 POST 请求将图像上传到 Firebase 存储
【发布时间】:2021-01-20 11:32:49
【问题描述】:

我创建了一个 Chrome 扩展程序,用于截取当前选项卡的屏幕截图。然后我想将图片上传到 Firebase。

chrome.tabs.captureVisibleTab 在 dataUrl string [docs] 返回,我尝试将其作为 formData 包含到 POST 请求中,如下所示:

screenshotBtn.onclick = function(){
  // generate the screenshot
  chrome.tabs.captureVisibleTab(null, { format: 'png', quality: 80 }, function(dataUrl){
    // console.log(dataUrl);

    // create imageBlob from data
    let imgBlob = b64toBlob(dataUrl.replace('data:image/png;base64,', ''), "image/png");
    console.log('imgBlob: ', imgBlob);
    
    let formData = new FormData();
    formData.append('image', imgBlob);

    // upload to Firebase Storage
    let url = endpoint + '/uploadImage';
    fetch(url, {
      method: 'POST',
      headers: {
        'Content-Type': false
      },
      body: formData
    })
    .then((response) => response.json())
    .then(data => {
      console.log(data);
    });
  });
};

(函数b64toBlob取自这个Stackoverflow Post

我尝试处理图像并将其上传到我服务器上的 Firebase,如下所示:

app.post("/api/uploadImage", (req, res) => {
    (async () => {
        try {
            console.log(req.body.image);
            // req.body.image = image in base64 format
            await uploadFile(req.body.image);
            return res.status(200).send();
        } catch(error){
            console.log(error);
            return res.status(500).send(error);
        }
    })();
});

async function uploadFile(imageBlob){
    const metadata = {
        metadata: {
            firebaseStorageDownloadTokens: uuid()
        },
        contentType: 'image/jpeg',
        cacheControl: 'public, max-age=31536000'
    };

    await bucket.upload(imageBlob, {
        gzip: true,
        metadata: metadata,
    });
}

我无法判断问题是否存在

  1. POST 请求的格式化方式
  2. 在服务器上接收文件的方式

我目前收到 500 错误,请求如下所示:

【问题讨论】:

  • req.body 可能无法处理二进制数据。因此,要么 1. 添加 Express 扩展来处理二进制数据,要么 2. 您可以发送 base64 数据并在服务器端转换回 blob,而不是发送二进制数据。

标签: javascript firebase google-chrome-extension firebase-storage


【解决方案1】:

我能够拼凑出一个可行的解决方案。

用于在客户端提交 POST 请求:

screenshotBtn.onclick = function(){
  // generate the screenshot
  chrome.tabs.captureVisibleTab(null, { format: 'png', quality: 80 }, function(dataUrl){

    let body = {
      "image" : dataUrl
    };

    // upload to Firebase Storage
    let url = endpoint + '/uploadImage';
    fetch(url, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(body)
    })
    .then((response) => response.json())
    .then(data => {
      console.log(data);
    });
  });
};

在服务器上:

// upload to storage
app.post("/api/uploadImage", (req, res) => {
    let image = req.body.image;
    let base64EncodedImageString = image.replace('data:image/png;base64,', '');
    let imageBuffer = new Buffer.from(base64EncodedImageString, 'base64');    
    let file = bucket.file("test-image.png");

    file.save(imageBuffer, {
        metadata: { 
            metadata: {
                firebaseStorageDownloadTokens: uuid
            },
        contentType: 'image/png',
        cacheControl: 'public, max-age=31536000',
        public: true,
        validation: 'md5'
        }
    }, (error) => {
        if(error){
            res.status(500).send(error);
        }
        return res.status(200).send('finished uploading');
    });
});

其中bucketadmin.storage().bucket()adminfirebase-admin 的一个实例,已使用我的凭据正确初始化)

请注意,除非提供 uuid,否则该图像会被列为已上传到 Firebase 存储,但您实际上无法查看或下载它(您只会看到一个旋转加载占位符)。

这些帖子对解决这个问题特别有帮助:

https://stackoverflow.com/a/46999645/1720985 https://github.com/firebase/firebase-admin-node/issues/694#issuecomment-583141427

【讨论】:

    猜你喜欢
    • 2020-09-08
    • 1970-01-01
    • 2017-09-25
    • 1970-01-01
    • 2018-10-24
    • 2019-01-22
    相关资源
    最近更新 更多