【问题标题】:Cloudinary client-side direct upload without jQueryCloudinary 客户端直接上传,无需 jQuery
【发布时间】:2015-03-29 08:33:48
【问题描述】:

我正在使用没有 jQuery 的 Cloudinary,并尝试通过浏览器直接上传。

我按照HERE 的指示创建了一个名为seller 的上传预设。

问题是,当我从客户端(使用 Angular)发帖时,我得到了响应:

XMLHttpRequest cannot load https://api.cloudinary.com/v1_1/mycloud/image/upload. Credentials flag is 'true', but the 'Access-Control-Allow-Credentials' header is ''. It must be 'true' to allow credentials.

据我了解,这是一个 CORS 问题。我正在提出如下所示的请求。

req =
  method: 'POST'
  url: 'https://api.cloudinary.com/v1_1/mycloud/image/upload'
  headers:
    'Access-Control-Allow-Credentials': 'true'
  file: scope.file
  data:
    upload_preset: 'seller'
$http(req)
  .success (data, status, headers, config) ->
    console.log 'file is uploaded successfully. Response: ' + data
  .error (err) ->
    console.log 'file error', err

我错过了什么?没有他们的 jQuery 插件就不能直接上传 Cloudinary 吗?

【问题讨论】:

    标签: angularjs cors cloudinary


    【解决方案1】:

    这是一个使用 AngularJS 1.3 的工作解决方案,可以在没有 jQuery 插件的情况下在 cloudinary 上执行直接未签名上传:

    var file = /* your file */;
    var cloud_name = 'your cloud_name';
    
    var fd = new FormData();
    
    fd.append('upload_preset', 'seller');
    fd.append('file', file);
    
    $http
        .post('https://api.cloudinary.com/v1_1/' + cloud_name + '/image/upload', fd, {
            headers: {
                'Content-Type': undefined,
                'X-Requested-With': 'XMLHttpRequest'
            }
        })
        .success(function (cloudinaryResponse) {
    
            // do stuff with cloudinary response
            // cloudinaryResponse = { public_id: ..., etc. }
    
        })
        .error(function (reponse) {
    
    
        });
    

    【讨论】:

    • 请添加更多详细信息
    • 喜欢添加一些关于你的答案的解释
    • 我更改了代码以准确回答最初的问题。代码更简单,其余代码是基本的:它以常规角度方式上传文件,并且不尝试像 @Tal Lev-Ami 建议的那样传递任何其他标题(如 Access-Control-Allow-Credentials)
    • var file = /* your file */; 是什么意思??这完全令人困惑。它是如何被填充的?你需要new FormData() 做什么?您必须使用那些 exact 标头吗?
    • /* your file */ 通常是 File object,由此处的文件 API 定义:w3.org/TR/FileAPI/#fileFormData 用于通过 XMLHttpRequest 发送表单数据比以前更容易。但是你可以不用它:developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/…
    【解决方案2】:

    让我们都花点时间指出 Cloudinary 的文档是多么可怕。这很容易是我见过的最糟糕的。噩梦燃料。

    现在我已经摆脱了这个想法......我真的需要能够做到这一点,我绝对不想安装他们庞大的库来做到这一点,我也不想与 JQuery 有任何关系(哈哈)。我花了太长时间把头撞在墙上,本来应该非常简单 - 但是 - 就是这样......

    服务器(Node.js)

    您需要一个向前端返回签名-时间戳对的端点:

    import cloudinary from 'cloudinary'
    
    export async function createImageUpload() {
      const timestamp = new Date().getTime()
      const signature = await cloudinary.utils.api_sign_request(
        {
          timestamp,
        },
        process.env.CLOUDINARY_SECRET
      )
      return { timestamp, signature }
    }
    

    客户端(浏览器)

    客户端向服务器请求签名-时间戳对,然后使用它上传文件。示例中使用的文件应来自 <input type='file'/> 更改事件等。

    const CLOUD_NAME = process.env.CLOUDINARY_CLOUD_NAME
    const API_KEY = process.env.CLOUDINARY_API_KEY
    
    async function uploadImage(file) {
      const { signature, timestamp } = await api.post('/image-upload')
      const form = new FormData()
      form.append('file', file)
      const res = await fetch(
        `https://api.cloudinary.com/v1_1/${CLOUD_NAME}/image/upload?api_key=${API_KEY}&timestamp=${timestamp}&signature=${signature}`,
        {
          method: 'POST',
          body: form,
        }
      )
      const data = await res.json()
      return data.secure_url
    }
    

    就是这样。这就是它所需要的。要是 Cloudinary 在他们的文档中有这个就好了。

    【讨论】:

      【解决方案3】:

      要解决许多与 CORS 相关的问题和浏览器不兼容问题,最好使用来自 jquery.cloudinary.js 的基于 jQuery 的上传器或 ng-file-upload。你可以在这里看到这两个例子 - https://github.com/cloudinary/cloudinary_angular/tree/master/samples/photo_album

      特别是,由于您传递的 Access-Control-Allow-Credentials 标头,CORS 请求被拒绝。请尝试删除它。

      【讨论】:

        【解决方案4】:

        如果有人正在寻找 Angular ng-flow + cloudinary 解决方案,我在这里创建了一个基本设置

        https://gist.github.com/maruf89/5528df53b133d442b292

        【讨论】:

          【解决方案5】:

          按照本教程获取简单的解决方案,效果很好..

          http://prasanthco.de/tutorials/cloudinary-image-upload-using-angularjs/

          这样做。

          Index.html - 以相同的顺序包含文件..

          <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
          <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.16.1/lodash.min.js"></script>
          <script src="https://github.com/cloudinary/pkg-cloudinary-core/blob/master/cloudinary-core.min.js"></script>
          <script src="https://cdnjs.cloudflare.com/ajax/libs/danialfarid-angular-file-upload/12.2.11/ng-file-upload-shim.min.js"></script>
          <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.3/angular.min.js"></script>
          <script src="https://github.com/cloudinary/cloudinary_angular/blob/master/js/angular.cloudinary.js"></script>
          <script src="https://cdnjs.cloudflare.com/ajax/libs/danialfarid-angular-file-upload/12.2.11/ng-file-upload.min.js"></script>
          

          app.js - 注入模块

          var app = angular.module('myApp', [
            'cloudinary',
            'ngFileUpload'
          ]);
          

          home.html - 任何需要图片上传选项的视图

          <div class="container" ng-hide="loader">
            <div class="deal">
              <label class="black bold">Upload an Image</label>
              <br>
              <div id="direct_upload"
                   ngf-drop="uploadFiles($files)"
                   ngf-drag-over-class="dragOverClass($event)"
                   ng-model="files"
                   ng-multiple="true">
                  <form>
                      <div class="form_line">
                          <div class="form_controls">
                              <div class="upload_button_holder">
                                  <div href="#" class="button" style="width:150px;" ngf-select="uploadFiles($files)" multiple title="upload" resetOnClick="true" >Upload</div>
                              </div>
                          </div>
                          <br>
                      </div>
                  </form>
              </div>
              <br>
          </div>
          

          home.s - 适当的控制器

          app.controller('homeController', ['$scope','$http', 'Upload', 'cloudinary', function ($scope, $http, $upload, cloudinary) {
          
          var cloud_name = "your cloud name";
          var api_key = "your api_key";
          var public_id = "your public_id";
          var signature = "your signature";
          var timestamp = "your timestamp";
          
          $scope.uploadFiles = function(files){
          
              if(!files){
                return false;
              }        
          
              angular.forEach(files, function(file){
                  if (file && !file.$error) {
                      file.upload = $upload.upload({
                        url: "https://api.cloudinary.com/v1_1/" + cloud_name + "/upload",
                        data: {
                            timestamp: timestamp,
                            public_id: public_id,
                            api_key: api_key,
                            signature: signature,
                            file: file
                        }
                      }).progress(function (e) {
                          file.progress = Math.round((e.loaded * 100.0) / e.total);
                          file.status = "Uploading... " + file.progress + "%";
                      }).success(function (data) {
                          console.log('success');
                          console.log(data);
                          alert('success');
                      }).error(function (data) {
                          console.log('failed');
                          console.log(data);
                          alert('failed');
                      });
                  }
              });
          };
          
          }]);
          

          希望这会有所帮助:)

          【讨论】:

            猜你喜欢
            • 2020-12-20
            • 2014-10-21
            • 2013-11-05
            • 2014-01-19
            • 1970-01-01
            • 2012-10-16
            • 2014-11-29
            • 2014-02-21
            • 2016-09-09
            相关资源
            最近更新 更多