【问题标题】:Is there any way to upload more than 10 MB file from Salesforce using HTTP Request to Dropbox?有没有办法使用 HTTP 请求从 Salesforce 上传超过 10 MB 的文件到 Dropbox?
【发布时间】:2021-09-21 16:15:39
【问题描述】:

下面的代码在 10 MB 上运行完美,但是当我尝试上传超过 20 MB 的文件时,它会引发错误。

private string TOKEN = 'access_token_of_dropbox_app';
string folderPathWithFileName;
for(ContentVersion contentVersionRec : [SELECT PathOnClient, VersionData 
                                        FROM contentversion
                                        WHERE contentdocumentId IN : contentDocumentIdSet]){
    folderPathWithFileName = '/Root/'+PathOnClient;//PathOnClient contains file name with extension 
    //like imagefile.png
    system.debug('###folderPathWithFileName=>'+folderPathWithFileName);
    Http http = new Http();
    HttpRequest httpReq = new HttpRequest();
    httpReq.setEndpoint('https://content.dropboxapi.com/2/files/upload');
    httpReq.setMethod('POST');
    httpReq.setHeader('Authorization','Bearer ' + TOKEN);
    httpReq.setHeader('Content-Type','application/octet-stream');
    httpReq.setHeader('Dropbox-API-Arg','{"path":"'+folderPath+'","mode":{".tag":"add"}}');
    httpReq.setBodyAsBlob(contentVersionRec.VersionData);
    HttpResponse httpResponse = http.send(httpReq);
    System.debug('res###' + httpResponse);
    System.debug('res.getBody()###'+httpResponse.getBody());
    if (httpResponse.getStatusCode() == 200) {
        System.debug('##Congratulations File Uploaded successfully :) =>'+httpResponse.getBody());
    }else{
        //Handle code here when file not uploaded. 
    }
}

当我尝试上传 20 MB 文件时,它会引发错误:

System.CalloutException:请求大小为 12001280 时超出最大大小限制 12000000

上面的代码在 queueable(Async) apex 中运行,并且该 queueable apex 从触发器中触发。所以我能够成功上传 10 MB 的文件。我也知道 ASYNC apex 中堆大小为 12 MB 的限制。 但想知道有没有办法将文件从 salesforce 上传到超过 10 MB 的 Dropbox。我想从 apex HTTP 请求上传最大 100 MB 的文件到 Dropbox。

注意:dropbox API 还允许我们以块的形式上传数据,这意味着我们可以使用 apex HTTP 请求以块的形式向 dropbox 发送数据。但挑战在于,首先制作块时,我们需要将 blob 数据转换为字符串或 base64 以制作多个块。它可以在 7-8 MB 上正常工作,但是当我们有 20 MB 以上时,它也会在将 blob 转换为字符串或 base64 时引发堆大小错误。

【问题讨论】:

    标签: salesforce dropbox-api apex-code


    【解决方案1】:

    有趣的问题!也可以试试https://salesforce.stackexchange.com/

    看看你是否可以使用保管箱插件https://appexchange.salesforce.com/appxListingDetail?listingId=a0N30000000prqLEAQ。它可能附带一些您可以调用的 Apex 或 JavaScript 内置插件,您必须检查包中是否有标记为 global 的方法和/或直接联系 Dropbox。

    或者您是否考虑过其他存储提供商?内置支持 Google Drive、SharePoint、OneDrive 和 Box,称为 Files Connect。这有点俗气,5岁但体面:https://www.youtube.com/watch?v=aG3m3zP00KQ

    如果做不到这一点 - 在纯顶点中您无能为力,这是一个硬性限制。您可以通过将文件“下载”到 JavaScript、将其分块并将其直接发送到 Dropbox 或通过 Apex 服务(如果您想将 API 密钥保留在服务器端)来实现。

    您可以逆转流程。 Dropbox 可以拉文件还是只推文件?如果不是 - 你可以向另一个应用程序发送通知(比如托管在 Heroku 上),它会登录到 SF(或者你可以传递当前用户的会话 ID),它会通过 SF 标准 API 提取文档,然后发送它.我想你会为带宽付费,但它可以工作得很好,特别是如果你把这个应用程序作为一个“画布”,这样它就可以很好地与 Salesforce 的其他部分集成,当前用户将被静默登录......

    【讨论】:

    • 至于让 Dropbox “拉”,而不是上传到它,Dropbox 确实提供了the /2/files/save_url endpoint,如果你能获得文件的 URL,它可能在这里工作。
    • @Greg 文件必须公开可见,对吗?棘手。您可以在 SF 中公开文件,但我感觉这些文件将隐藏在登录之后,这意味着 Dropbox 必须输入 Authorization Bearer <sf session id goes here> 或提供 JWT 令牌或其他一些 OAuth2 技巧......嗯。同样,如果您有中间服务器,您可以提取文件,将其公开到保管箱并在几分钟后删除。
    • 是的,没错,它需要可公开访问。 Dropbox 不提供添加标头或凭据的方法。
    • 感谢 Eyescream 和 Greg 的帮助。 Dropbox save_url 对我有用。我首先创建了内容分发记录,然后我通过 ContentDistribution.ContentDownloadUrl 上传到 save_url 端点,上传所有文件后,我正在删除内容分发记录。再次感谢您的帮助:)
    【解决方案2】:

    嗯...这也是我们也在努力解决的问题。克服这些限制的答案是基于架构。如果您使用 LWC 或 AURA 组件将文件上传/下载到 dropbox api,您可以使用 Javascript 而不是 APEX。在这种情况下,您必须与 CSP 和 CORS 限制和问题作斗争。

    Javascript 在浏览器内的客户端执行,并且浏览器的 RAM 使用限制。我认为几乎在所有情况下,客户端资源都远大于 12 MB 的 RAM。

    我不知道 APEX 中的任何流式传输概念,因此任何内容都必须符合堆大小限制。

    一旦 Salesforce 启用 Evergreen,您可能会使用 Evergreen 来克服这个限制,它不在 Salesforce 平台内运行,而是在 heroku 平台内运行(我猜)。这个平台按需提供资源,应该有更高的限制。

    https://developer.salesforce.com/blogs/2019/11/introducing-salesforce-evergreen

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-04-09
      • 1970-01-01
      • 2018-06-06
      • 2019-06-29
      • 2017-11-09
      • 2011-09-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多