當試圖上傳文件到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">×</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
我需要更多的信息,如版本精細上傳的,和一個完整的'debug'選項設置爲'true'的一組日誌。 –
版本是5.5.0。我將編輯帖子併發布日誌 –