1

我正在使用 Force.com Apex 和 VF,试图利用 Cloudinary 进行一些内容管理。我在 Chrome 中遇到了以下问题(不知道为什么它显示“未定义”,因为云名称是在 JS 中定义的):

POST https://api.cloudinary.com/v1_1/undefined/upload 401 (Unauthorized)    ......    api.cloudinary.com/v1_1/undefined/upload:1

在沮丧的时候真的很感激任何帮助。这是代码(注意注释):

  • 顶点

public String getCldSig() {

        Datetime d = datetime.now();
        Long uxtime = d.getTime() / 1000; //method provides epoch/unix time
        String apisec = '<some_secret>';
        String serial = 'callback=<some_url>&public_id=<some_id>&timestamp=' + uxtime + apisec;
        Blob sha = Crypto.generateDigest('SHA1', Blob.valueOf(serial));
        String sig = EncodingUtil.convertToHex(sha); //perhaps I need to do UTF-8
        String jsoSerial = '{"public_id":"<some_Id>",';
        jsoSerial += '"timestamp":"'+ uxtime + '",'; 
        jsoSerial += '"callback":"<some_url>",';  //maybe an issue with hosting the CORS html on a VF page.
        jsoSerial += '"signature":"' + sig + '",'; 
        jsoSerial += '"api_key":"<some_key>"}';
        return jsoSerial.escapeHtml3(); //seems to be the right escape output HTML
}
  • Javascript/jQuery:

                    $.cloudinary.config({"api_key":"<some_key>", "cloud_name":"<some_id>"});                       
                    $('.cloudinary-fileupload')
                      .fileupload({ 
                        dropZone: ".sceneUpBtn",
                        progress: function (e, data) {
                          $(".progress").text("Uploading... " + Math.round((data.loaded * 100.0) / data.total) + "%");
                        }
                      });
                    $('.cloudinary-fileupload').bind('fileuploadstart', function(e){
                      $('.sceneUpPrev').html('Upload started...');
                    });                     
                    $('.cloudinary-fileupload').bind('fileuploadfail', function(e){
                      $('.sceneUpPrev').html($.cloudinary.error); //**due to lack of documentation don't know how to get any specific error message using the jQuery library. Would expect messages similar to AWS S3
                    });     
                    $('.cloudinary-fileupload').bind('cloudinarydone', function(e, data) {  
                        $('.sceneUpPrev').html(
                           $.cloudinary.image(data.result.public_id, 
                               { format: data.result.format, version: data.result.version, 
                                 crop: 'scale', width: 200 }));    
                        $('.image_public_id').val(data.result.public_id);    
                        return true;
                    }); 
    

输入 HTML:

<input class="cloudinary-fileupload" 
data-cloudinary-field="upref" 
data-form-data="&quot;public_id&quot;:&quot;<some_id>&quot;,&quot;timestamp&quot;:&quot;1372282433&quot;,&quot;callback&quot;:&quot;<some_url>&quot;,&quot;signature&quot;:&quot;<some_sig>&quot;,&quot;api_key&quot;:&quot;<some_key>&quot;}" 
id="sceneUpload" 
name="file" 
type="file">
4

2 回答 2

2

POST url 的“未定义”部分意味着 Cloudinary 的 jQuery 库在生成 POST url 时无法确定 cloud_name。这很可能是因为 $.cloudinary.config 函数调用得太晚了。请将此调用移到 $(document).ready 或类似结构之外。

另一个(不相关的)点 - 第二行中的选择器缺少一个“。” 它应该是 $('.cloudinary-fileupload')

于 2013-06-27T06:30:14.800 回答
1

在 Cloudinary 的 Tal 的大力帮助下,我取得了成功!我将回顾一下解决方案:

  1. 不要在 $(document).ready() 中实例化 Cloudinary 的库,而是直接将其插入脚本部分

        <script type="text/javascript">             
        $.cloudinary.config({"api_key":"<key>","cloud_name":"<cloud_name>"});
    
  2. 使用 FileUpload 小部件实例化 formData,这可以确保 fileUpload
    加载您的 json 发送参数(这是一个时间问题)。

                        $('.cloudinary-fileupload').fileupload({ 
                            formData : <unescaped json params>,
                            dropZone: $('.sceneUpBtn'),                             
                            dataType: 'json',
                            done: function (e, data) {
                                $.each(data.result.files, function (index, file) {
                                    $('<p/>').text(file.name).appendTo('#filename');
                                });
                                },
                            progressall: function (e, data) {
                                var progress = parseInt(data.loaded / data.total * 100, 10);
                                $('.sceneUpBar').css('width',progress + '%');
                            }
                    });
    
  3. 将签名参数与发送到服务器的 json 参数匹配。在 Apex 中签名并返回 json,如下所示:

    public String getCloudinarySig() {
        Datetime d = datetime.now();
        Long uxtime = d.getTime() / 1000; //epoch unix time method in force.com
        String apisec = '<secret>';
        String serial = 'callback=<cors url>&timestamp=' + uxtime + apisec; //Signature needs params here need to match json params below
        Blob sha = Crypto.generateDigest('SHA1', Blob.valueOf(serial)); //Sha1 digest
        String sig = EncodingUtil.convertToHex(sha); //Hex conversion
        String jsoSerial = '{';
        jsoSerial += '"api_key":"<key>",'; //these json params need to match signature params above     
        jsoSerial += '"<CORS_url>",';                   
        jsoSerial += '"signature":"' + sig + '",';  
        jsoSerial += '"timestamp":'+ uxtime; 
        jsoSerial += '}';
        return jsoSerial;       
    

    }

很高兴回答任何问题...

于 2013-07-01T06:25:43.540 回答