2016-02-15 32 views
0

當試圖上傳文件到s3存儲桶時,我不斷收到「策略簽名失敗的錯誤」,「從服務器收到一個空的或無效的響應!」和「POST請求0失敗 - 響應代碼404「。我已經遵循教程並通過Facebook應用配置了應用,並將Facebook設置爲AWS IAM角色中的ID提供者。獲取策略簽名失敗錯誤並收到服務器發出的空白或無效響應!與罰款上傳無服務器上傳

我可以將文件放入框中,但是錯誤公式爲:收到服務器的空或無效響應!

這裏是我的代碼:

artwork.js

'use strict'; 

/** 
* @ngdoc function 
* @name artvoicesApp.controller:MainCtrl 
* @description 
* # MainCtrl 
* Controller of the artvoicesApp 
*/ 
angular.module('artvoicesApp') 
    .controller('ArtworkCtrl', ['$scope', '$firebaseObject', 'FIREBASE_URL', 'Auth', '$state', function ($scope, $firebaseObject, FIREBASE_URL, Auth, $state) { 

    var artist = FIREBASE_URL.child('data/artists/'); 
    var artistObject = $firebaseObject(artist); 
    var authData = Auth.$getAuth(); 
    var token = authData.facebook.accessToken; 
    $scope.newArt = {}; 

    artistObject.$loaded().then(function() { 
     $scope.artist = artistObject; 
    }); 

    var artwork = FIREBASE_URL.child('data/artists/artwork'); 
    var artworkObject = $firebaseObject(artwork); 

    artworkObject.$loaded().then(function() { 
     $scope.artwork = artworkObject; 
    }); 

    $scope.submitNewArt = function() { 
     artwork.push({name: $scope.newArt.name, status: $scope.newArt.status, height: $scope.newArt.height, width: $scope.newArt.width, value: $scope.newArt.value}); 
    }; 

    $scope.editData = function(data, k, c) { //k is for key, c is for category 
     artworkObject[k][c] = data; 
     artworkObject.$save().then(function() {}, function(e) { 
     console.log(e); 
     }); 
    }; 

    $scope.logout = function() { 
     Auth.$unauth(); 
     $state.go('login'); 
    }; 

    var s3Globals = { 
     userName: authData.facebook.displayName, 
     roleArn: 'arn:aws:iam::875128865884:role/facebook-idp-role', 
     token: authData.facebook.accessToken 
    }; 


    $(function() { 
     var assumeRoleWithWebIdentity = function(params) { 
       var sts = new AWS.STS(), 
        assumeRoleParams = {}; 
       // s3Globals.roleArn = s3Globals.roleArn; 
       // s3Globals.providerId = s3Globals.providerId; 
       //params.idToken || s3Globals.idToken; 

       assumeRoleParams = { 
        ProviderId: 'graph.facebook.com', 
        RoleArn: s3Globals.roleArn, 
        RoleSessionName: "web-identity-federation", 
        WebIdentityToken: s3Globals.token 
       }; 

       // if (s3Globals.providerId) { 
       //  assumeRoleParams.ProviderId = s3Globals.providerId; 
       // } 

       sts.assumeRoleWithWebIdentity(assumeRoleParams, params.callback || s3Globals.updateCredentials); 
      }, 
      getFuCredentials = function(data) { 
       return { 
        accessKey: data.Credentials.AccessKeyId, 
        secretKey: data.Credentials.SecretAccessKey, 
        sessionToken: data.Credentials.SessionToken, 
        expiration: data.Credentials.Expiration 
       }; 
      }; 

     s3Globals.assumeRoleWithWebIdentity = assumeRoleWithWebIdentity; 
     s3Globals.getFuCredentials = getFuCredentials; 
    }); 

    $(function() { 
     var bucketUrl = "https://artvoicestest.s3.amazonaws.com", 
      updateCredentials = function(error, data) { 
       if (!error) { 
        $('#uploader').fineUploaderS3("setCredentials", s3Globals.getFuCredentials(data)); 
       } 
      }; 

     $("#uploader").fineUploaderS3({ 
      request: { 
       endpoint: bucketUrl 
      }, 
      objectProperties: { 
       // Since we want all items to be publicly accessible w/out a server to return a signed URL 
       acl: "public-read", 

       //The key for each file will follow this format: {USER_NAME}/{UUID}.{FILE_EXTENSION} 
       key: function(id) { 
        var filename = this.getName(id), 
         uuid = this.getUuid(id); 

        return qq.format("{}/{}.{}", s3Globals.userName, uuid, qq.getExtension(filename)); 
       } 
      }, 
      chunking: { 
       enabled: true 
      }, 
      resume: { 
       enabled: true 
      }, 
      // Restrict files to 15 MB and 5 net files per session 
      validation: { 
       itemLimit: 5, 
       sizeLimit: 15000000 
      }, 
      thumbnails: { 
       placeholders: { 
        notAvailablePath: "not_available-generic.png", 
        waitingPath: "waiting-generic.png" 
       } 
      } 
     }) 
      .on('complete', function(event, id, name, response, xhr) { 
       var $fileEl = $(this).fineUploaderS3("getItemByFileId", id), 
        $viewBtn = $fileEl.find(".view-btn"), 
        key = $(this).fineUploaderS3("getKey", id); 

       // Add a "view" button to access the uploaded file in S3 if the upload is successful 
       if (response.success) { 
        $viewBtn.show(); 
        $viewBtn.attr("href", bucketUrl + "/" + key); 
       } 
      }) 
      .on("credentialsExpired", function() { 
       var promise = new qq.Promise(); 

       // Grab new credentials 
       s3Globals.assumeRoleWithWebIdentity({ 
        callback: function(error, data) { 
         if (error) { 
          promise.failure("Failed to assume role"); 
         } 
         else { 
          promise.success(s3Globals.getFuCredentials(data)); 
         } 
        } 
       }); 

       return promise; 
      }); 

     s3Globals.updateCredentials = updateCredentials; 
     // $(document).on("tokenReceived.s3", function() { 
     //  $("#uploader").show(); 
     // }); 
     // $(document).trigger("tokenExpired.s3"); 
    }); 

    }]); 

的index.html

<script type="text/template" id="qq-template"> 
     <div class="qq-uploader-selector qq-uploader" qq-drop-area-text="Drop files here"> 
      <div class="qq-total-progress-bar-container-selector qq-total-progress-bar-container"> 
       <div role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" class="qq-total-progress-bar-selector qq-progress-bar qq-total-progress-bar"></div> 
      </div> 
      <div class="qq-upload-drop-area-selector qq-upload-drop-area" qq-hide-dropzone> 
       <span class="qq-upload-drop-area-text-selector"></span> 
      </div> 
      <div class="qq-upload-button-selector qq-upload-button"> 
       <div>Upload a file</div> 
      </div> 
       <span class="qq-drop-processing-selector qq-drop-processing"> 
        <span>Processing dropped files...</span> 
        <span class="qq-drop-processing-spinner-selector qq-drop-processing-spinner"></span> 
       </span> 
      <ul class="qq-upload-list-selector qq-upload-list" aria-live="polite" aria-relevant="additions removals"> 
       <li> 
        <div class="qq-progress-bar-container-selector"> 
         <div role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" class="qq-progress-bar-selector qq-progress-bar"></div> 
        </div> 
        <span class="qq-upload-spinner-selector qq-upload-spinner"></span> 
        <span class="qq-upload-file-selector qq-upload-file"></span> 
        <span class="qq-edit-filename-icon-selector qq-edit-filename-icon" aria-label="Edit filename"></span> 
        <input class="qq-edit-filename-selector qq-edit-filename" tabindex="0" type="text"> 
        <span class="qq-upload-size-selector qq-upload-size"></span> 
        <button type="button" class="qq-btn qq-upload-cancel-selector qq-upload-cancel">Cancel</button> 
        <button type="button" class="qq-btn qq-upload-retry-selector qq-upload-retry">Retry</button> 
        <button type="button" class="qq-btn qq-upload-delete-selector qq-upload-delete">Delete</button> 
        <span role="status" class="qq-upload-status-text-selector qq-upload-status-text"></span> 
       </li> 
      </ul> 

      <dialog class="qq-alert-dialog-selector"> 
       <div class="qq-dialog-message-selector"></div> 
       <div class="qq-dialog-buttons"> 
        <button type="button" class="qq-cancel-button-selector">Close</button> 
       </div> 
      </dialog> 

      <dialog class="qq-confirm-dialog-selector"> 
       <div class="qq-dialog-message-selector"></div> 
       <div class="qq-dialog-buttons"> 
        <button type="button" class="qq-cancel-button-selector">No</button> 
        <button type="button" class="qq-ok-button-selector">Yes</button> 
       </div> 
      </dialog> 

      <dialog class="qq-prompt-dialog-selector"> 
       <div class="qq-dialog-message-selector"></div> 
       <input type="text"> 
       <div class="qq-dialog-buttons"> 
        <button type="button" class="qq-cancel-button-selector">Cancel</button> 
        <button type="button" class="qq-ok-button-selector">Ok</button> 
       </div> 
      </dialog> 
     </div> 
    </script> 

    <script>var s3DemoGlobals = {};</script> 


    <!-- endbuild --> 
    <script type="text/javascript"> 
     !function(){var analytics=window.analytics=window.analytics||[];if(!analytics.initialize)if(analytics.invoked)window.console&&console.error&&console.error("Segment snippet included twice.");else{analytics.invoked=!0;analytics.methods=["trackSubmit","trackClick","trackLink","trackForm","pageview","identify","reset","group","track","ready","alias","page","once","off","on"];analytics.factory=function(t){return function(){var e=Array.prototype.slice.call(arguments);e.unshift(t);analytics.push(e);return analytics}};for(var t=0;t<analytics.methods.length;t++){var e=analytics.methods[t];analytics[e]=analytics.factory(e)}analytics.load=function(t){var e=document.createElement("script");e.type="text/javascript";e.async=!0;e.src=("https:"===document.location.protocol?"https://":"http://")+"cdn.segment.com/analytics.js/v1/"+t+"/analytics.min.js";var n=document.getElementsByTagName("script")[0];n.parentNode.insertBefore(e,n)};analytics.SNIPPET_VERSION="3.1.0"; 
     analytics.load("0A4Y3sUzm9iPLwDEcwyLoxaDvicWeiws"); 
     analytics.page() 
     }}(); 
    </script> 
    </head> 
    <body ng-app="artvoicesApp"> 
    <!--[if lte IE 8]> 
     <p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.</p> 
    <![endif]--> 

    <!-- Add your site or application content here --> 
    <!-- <div class="header"> 
     <div class="navbar navbar-default" role="navigation"> 
     <div class="container"> 
      <div class="navbar-header"> 

      <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#js-navbar-collapse"> 
       <span class="sr-only">Toggle navigation</span> 
       <span class="icon-bar"></span> 
       <span class="icon-bar"></span> 
       <span class="icon-bar"></span> 
      </button> 

      <a class="navbar-brand" style="text-align: center" href="#/">ArtVoices</a> 
      </div> 

      <div class="collapse navbar-collapse" id="js-navbar-collapse"> 

      <ul class="nav navbar-nav"> 
      </ul> 
      </div> 
     </div> 
     </div> 
    </div> --> 

    <!-- The element where Fine Uploader will exist. --> 


    <ui-view></ui-view> 


    <!-- Google Analytics: change UA-XXXXX-X to be your site's ID --> 
    <script> 
     !function(A,n,g,u,l,a,r){A.GoogleAnalyticsObject=l,A[l]=A[l]||function(){ 
     (A[l].q=A[l].q||[]).push(arguments)},A[l].l=+new Date,a=n.createElement(g), 
     r=n.getElementsByTagName(g)[0],a.src=u,r.parentNode.insertBefore(a,r) 
     }(window,document,'script','https://www.google-analytics.com/analytics.js','ga'); 

     ga('create', 'UA-XXXXX-X'); 
     ga('send', 'pageview'); 
    </script> 

    <!-- build:js(.) scripts/vendor.js --> 
    <!-- bower:js --> 
    <script src="bower_components/jquery/dist/jquery.js"></script> 
    <script src="bower_components/angular/angular.js"></script> 
    <script src="bower_components/bootstrap/dist/js/bootstrap.js"></script> 
    <script src="bower_components/angular-xeditable/dist/js/xeditable.js"></script> 
    <script src="bower_components/angular-animate/angular-animate.js"></script> 
    <script src="bower_components/angular-cookies/angular-cookies.js"></script> 
    <script src="bower_components/angular-resource/angular-resource.js"></script> 
    <script src="bower_components/angular-route/angular-route.js"></script> 
    <script src="bower_components/angular-sanitize/angular-sanitize.js"></script> 
    <script src="bower_components/angular-touch/angular-touch.js"></script> 
    <script src="bower_components/angular-ui-router/release/angular-ui-router.js"></script> 
    <script src="bower_components/firebase/firebase.js"></script> 
    <script src="bower_components/angularfire/dist/angularfire.js"></script> 
    <script src="bower_components/lodash/lodash.js"></script> 
    <script src="bower_components/cloudinary-core/cloudinary-core.js"></script> 
    <script src="bower_components/cloudinary_ng/js/angular.cloudinary.js"></script> 
    <script src="bower_components/animateCSS/dist/jquery.animatecss.js"></script> 
    <script src="https://sdk.amazonaws.com/js/aws-sdk-2.2.35.min.js"></script> 
    <script src="fine-uploader/s3.jquery.fine-uploader.min.js"></script> 



    <!-- endbowe-> 
    <!-- endbuild --> 

     <!-- build:js({.tmp,app}) scripts/scripts.js --> 
     <script src="scripts/app.js"></script> 
     <script src="scripts/controllers/artwork.js"></script> 
     <script src="scripts/controllers/auth.js"></script> 
     <script src="scripts/factories/authfactory.js"></script> 
     <script src="scripts/factories/login.js"></script> 
     <!-- endbuild --> 
</body> 
</html> 

artwork.html

上傳位於DIV ID =「上傳」

<div id="artwork-page" ng-cloak> 
    <div class="row"> 
    <div class="col-md-2 col-md-offset-1 col-sm-4 col-sm-offset-1 col-xs-4 col-xs-offset-1"> 
     <p><button class="btn btn-default" ng-click="logout()"><i class="fa fa-sign-out"></i> Logout</button></p> 
    </div> 
    </div> 
    <div class="row text-center"> 
    <h1 class="artist-name">{{artist.name}}</h1> 
    </div> 
    <div id="add-art-div"> 
    <a style="color: white" class="btn btn-success btn-lg" data-target="#add-art" data-toggle="modal"><i class="fa fa-plus"></i> Add Art</a> 
    </div> 
    <div id="stripe-div"> 

    </div> 
    <div class="add-art-modal"> 
    <!-- Modal --> 
    <div class="modal fade" id="add-art" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"> 
     <div class="modal-dialog" role="document"> 
     <div class="modal-content"> 
      <div class="modal-header"> 
      <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button> 
      <h4 class="modal-title" id="myModalLabel" style="text-align: center">Add Artwork</h4> 
      </div> 
      <div class="modal-body"> 
      <div class="row drag-drop-add"> 
       <div class="col-12 text-center"> 
       <div id="uploader"></div> 
       <p>Drop Image <i class="fa fa-arrow-up"></i></p> 
       </div> 
       <div class="col-sm-6 col-md-4 col-md-offset-1 text-center"> 
       <img src="images/audio_file.png" class="drag-image"> 
       <div id="fine-uploader"></div> 

       <p>Drop Audio <i class="fa fa-arrow-up"></i></p> 
       </div> 
      </div> 
      <form name="addArt" ng-submit="submitNewArt()" novalidate> 
       <div class="form-group row"> 
       <label for="exampleInputName2" class="col-sm-1 form-control-label">Name:</label> 
       <div class="col-sm-10 modal-input"> 
        <input type="text" class="form-control" id="exampleInputName2" ng-required="true" ng-model="newArt.name"> 
       </div> 
       </div> 
       <div class="form-group row"> 
       <label for="exampleInputValue" class="col-sm-1 form-control-label">Value:</label> 
       <div class="col-sm-10 modal-input"> 
        <input type="text" class="form-control" id="exampleInputValue" ng-required="true" ng-model="newArt.value"> 
       </div> 
       </div> 
       <div class="form-group row"> 
       <label for="exampleInputStatus" class="col-sm-1 form-control-label">Status:</label> 
       <div class="col-sm-10 modal-input"> 
        <input type="text" class="form-control" id="exampleInputStatus" ng-required="true" ng-model="newArt.status"> 
       </div> 
       </div> 
       <div class="form-group row"> 
       <label for="exampleInputHeight" class="col-sm-1 form-control-label">Height:</label> 
       <div class="col-sm-10 modal-input"> 
        <input type="text" class="form-control" id="exampleInputHeight" ng-required="true" ng-model="newArt.height"> 
       </div> 
       </div> 
       <div class="form-group row"> 
       <label for="exampleInputWidth" class="col-sm-1 form-control-label">Width:</label> 
       <div class="col-sm-10 modal-input"> 
        <input type="text" class="form-control" id="exampleInputWidth" ng-required="true" ng-model="newArt.width"> 
       </div> 
       </div> 
       <p class="warning" ng-show="addArt.$invalid">*All Items must be filled in to Add Item</p> 
       <div class="add-art"> 
       <button type="submit" class="btn btn-primary add-art" ng-disabled="addArt.$invalid">Submit Artwork</button> 
       </div> 
      </form> 
      </div> 
      <div class="modal-footer"> 
      <button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button> 
      </div> 
     </div> 
     </div> 
    </div> 
    </div> 
    <div class="row"> 
    <div class="card-columns"> 
     <div class="col-md-4 col-sm-6 col-xs-12 text-center" ng-repeat="(key, v) in artwork"> 
     <div class="card animated" ng-mouseenter="hover = true" ng-mouseleave="hover = false" ng-class="{pulse: hover}"> 
      <h4 class="card-title art-name">{{v.descriptionText}}</h4> 
      <img class="card-img-top artwork" src="{{v.imageUrl}}" alt="Card image cap"> 
      <p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p> 
      <ul class="list-group list-group-flush"> 
       <li class="list-group-item"><strong>Status:</strong> <button class="btn btn-normal" onbeforesave="editData($data, key, 'status')" editable-text="v.status">{{ v.status || "empty" }} <i class="fa fa-pencil-square-o"></i></button></li> 
       <li class="list-group-item"><strong>Price:</strong> <button class="btn btn-normal" onbeforesave="editData($data, key, 'value')" editable-text="v.value">${{ v.value || "empty" }} <i class="fa fa-pencil-square-o"></i></button></li> 
       <li class="list-group-item"><strong>Width:</strong> <button class="btn btn-normal" onbeforesave="editData($data, key, 'width')" editable-text="v.width">{{ v.width || "empty" }} <i class="fa fa-pencil-square-o"></i></button></li> 
       <li class="list-group-item"><strong>Height:</strong> <button class="btn btn-normal" onbeforesave="editData($data, key, 'height')" editable-text="v.height">{{ v.height || "empty" }} <i class="fa fa-pencil-square-o"></i></button></li> 
      </ul> 
     </div> 
     </div> 
    </div> 
    </div> 
</div> 

調試日誌

s3.jquery.fine-uploader.min.js:16 [Fine Uploader 5.5.0] Parsing template 
    s3.jquery.fine-uploader.min.js:16 [Fine Uploader 5.5.0] Template parsing complete 
    s3.jquery.fine-uploader.min.js:16 [Fine Uploader 5.5.0] Rendering template in DOM. 
    s3.jquery.fine-uploader.min.js:16 [Fine Uploader 5.5.0] Template rendering complete 
    http://localhost:9000/%7B%7Bv.imageUrl%7D%7D Failed to load resource: the server responded with a status of 404 (Not Found) 
    s3.jquery.fine-uploader.min.js:16 [Fine Uploader 5.5.0] Received 1 files. 
    s3.jquery.fine-uploader.min.js:16 [Fine Uploader 5.5.0] Attempting to validate image. 
    s3.jquery.fine-uploader.min.js:16 [Fine Uploader 5.5.0] Sending simple upload request for 0 
    s3.jquery.fine-uploader.min.js:16 [Fine Uploader 5.5.0] Submitting S3 signature request for 0 
    s3.jquery.fine-uploader.min.js:16 [Fine Uploader 5.5.0] Sending POST request for 0 
    http://localhost:9000/null Failed to load resource: the server responded with a status of 404 (Not Found) 
    s3.jquery.fine-uploader.min.js:16 [Fine Uploader 5.5.0] POST request for 0 has failed - response code 404qq.log @ s3.jquery.fine-uploader.min.js:16 
    s3.jquery.fine-uploader.min.js:16 [Fine Uploader 5.5.0] Error attempting to parse signature response: SyntaxError: Unexpected token Cqq.log @ s3.jquery.fine-uploader.min.js:16 
    s3.jquery.fine-uploader.min.js:16 [Fine Uploader 5.5.0] Received an empty or invalid response from the server!qq.log @ s3.jquery.fine-uploader.min.js:16 
    s3.jquery.fine-uploader.min.js:16 [Fine Uploader 5.5.0] Policy signing failed. Received an empty or invalid response from the server!qq.log @ s3.jquery.fine-uploader.min.js:16 
    s3.jquery.fine-uploader.min.js:16 [Fine Uploader 5.5.0] Simple upload request failed for 0 
+0

我需要更多的信息,如版本精細上傳的,和一個完整的'debug'選項設置爲'true'的一組日誌。 –

+0

版本是5.5.0。我將編輯帖子併發布日誌 –

回答

0

是精細上傳S3試圖發送一個簽名請求的事實表明,你是不是在第一個文件上傳之前通過選項或API提供任何種類的憑證。您需要設置一些中斷點,並找出代碼沒有提供臨時憑證的原因。

0

感謝您的反饋意見。你是對的。我在嘗試使用臨時憑證返回請求之前設置憑據。我最終將sts.assumeRoleWithWebIdentity函數放入承諾並在解決承諾後運行fineUploaderS3方法。下面是代碼:

s3Factory.js

angular.module('artvoicesApp') 
    .factory('s3Factory', ['$q', function ($q) { 

    var s3Object = {}; 

    s3Object.getTempCredentials = function(s3Globals) { 
     var defer = $q.defer(); 
     var assumeRoleParams = { 
      RoleArn: s3Globals.roleArn, 
      RoleSessionName: "web-identity-federation", 
      WebIdentityToken: s3Globals.token 
     }; 
     if (s3Globals.providerId) { 
     assumeRoleParams.ProviderId = s3Globals.providerId; 
     } 
     var sts = new AWS.STS(); 
     sts.assumeRoleWithWebIdentity(assumeRoleParams, function (err, data) { 
     if (err) { console.log(err, err.stack); } // an error occurred 
     else { defer.resolve(data);}   // successful response 
     }); 

     return defer.promise; 
    }; 

    s3Object.assignCredentials = function(data) { 
      return { 
       accessKey: data.Credentials.AccessKeyId, 
       secretKey: data.Credentials.SecretAccessKey, 
       sessionToken: data.Credentials.SessionToken, 
       expiration: data.Credentials.Expiration 
      }; 
    }; 

    return s3Object; 

    }]); 

artwork.js

s3Factory.getTempCredentials(s3Globals).then(function(data) { 
    $("#uploader").fineUploaderS3("setCredentials", s3Factory.assignCredentials(data)); 
    }); 
相關問題