asafdav / ng-s3upload Goto Github PK
View Code? Open in Web Editor NEWUpload to S3 using AngularJS
License: MIT License
Upload to S3 using AngularJS
License: MIT License
Hey just wondering what browsers this works with. Particularly interested in whether this works in IE8/9
Thanks
Currently the only way I can figure out how to access the S3 file url is to have a $watch on the model in my controller.
It seems like a better solution would be to have the the event s3upload:success
include the file url as an additional argument. Then I could simple add a listener in my controller and do whatever I wanted with the file url.
Is there already a better way to access the file url from the controller? If not is adding it to the events a good option?
I wanted to use the "getManualOptions" feature (b1c4d12), but I had trouble making it work. While debugging, I noticed that the include file build/ng-s3upload.js
does not contain the getManualOptions
feature. I got it working by simply running grunt
in bower_components/ng-s3upload
. I was including this file since wiredep
made this automatically.
Would be nice to add server side examples of how to work with that directive in Ruby, Node etc..
Or a link to something...
Hey here is my markup
<span s3-upload bucket="'bucket-name'" ng-model="foo"
s3-upload-options="{getOptionsUri: 'URI-to-json-response''}" ></span>
This throws out 403 forbidden error.
This is not working. Please help
Html code
<div s3-upload bucket="onnbikes" ng-model="product.remote_product_file_url"
s3-upload-options="{getOptionsUri: 'http://localhost:8080/myProject/getPresignedURLForS3', folder: 'images/'}">
My server URL - returns {
"key": "AKIAIY7TX476RMN4ULRA",
"signature": "4fRQEyo2BVOmFJYMq2boxruFjkc=",
"policy": "eyJleHBpcmF0aW9uIjogIjIwMTYtMTAtMTFUMTU6NTM6MTdaIiwiY29uZGl0aW9ucyI6IFt7ImJ1Y2tldCI6ICJvbm5iaWtlcyJ9LHsiYWNsIjogImVjMi1idW5kbGUtcmVhZCJ9LFsic3RhcnRzLXdpdGgiLCAiJGtleSIsICJpbWFnZSJdXX0="
}
But i get error
addBike.html:12:40
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://undefined.s3.amazonaws.com/. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing).
My CORS config is
_ GET POST PUT _Please help
Error1:
GET http://mybaseurl/function%20(elm,%20attrs)%20%7B%2…%20%20%20return%20'theme/'%20+%20theme%20+%20'.html';%20%20%20%20%20%20%7D 400 (Bad Request)
Error1 url decoded:
GET http://mybaseurl/function (elm, attrs) {%2… return 'theme/' theme '.html'; } 400 (Bad Request)
Error2:
Uncaught TypeError: h.match is not a function
I have loaded libraries in my index.html file and included the dependencies ngsanitize,ngs3upload
in my module but i am getting the above errors and the directive template is not showing up in my page.
There should be way to change the default random characters from 16
Cam we specify the full template path so we can use our own custom external routes. Maybe even allow the template path to be set as a directive option so we can use multiple variants of templates.
I am choosing images from the file system. What should the value of my ng-model be and how will it be useful for me
I must be missing something really simple.
Is there a way to specify the bucket
or s3-upload-options
in the controller instead of in-lining in the template?
For example, is the following setup possible?
myapp.controller('MyCtrl', function ($scope) {
$scope.s3 = {
bucket: 'mybucket',
options: { submitOnChange: false, getOptionsUri: '/api/v1/s3_options', folder: 'some/folder/' }
}
$scope.performUpload = false;
}
and the template like so:
<div data-ng-controller='MyCtrl'>
<div data-s3-upload
data-bucket="s3.bucket"
data-ng-model="files.first"
data-s3-upload-options="s3.options"
data-do-upload="performUpload">
</div>
</div
Thx again, this is a great library to use!
Hi @asafdav ,
I'm using your module for a project at work and I've stumbled on a couple of issues regarding the targetFilename
parameter.
First, when I try to use this parameter, I get some sort of an eval error; here is an example with '42.jpg':
<div
s3-upload bucket="'MY_BUCKET'" ng-model="driver.thumbnail"
s3-upload-options="{getOptionsUri: '/api/s3/credentials', folder: 'driver_faces/', targetFilename: '42.jpg' }">
</div>
// =>
Error: [$parse:syntax] Syntax Error: Token 'jpg' is an unexpected token at column 4 of the expression [42.jpg] starting at [jpg].
When I try a variable instead (let's say driver_id + '.jpg'
), the error happens on the value of this id:
Syntax Error: Token 'd8c4a9c98445ea1ffd8f2d.jpg' is an unexpected token ...
I had a look at the code and it seems that you are actually evaluating the targetFilename
parameter line 75 (scope.$eval(opts.targetFilename)
); I think the error comes from there and I don't understand the need for an eval
here; I think that what you get in this field has already been evaluated beforehand, and you get the right value straight Line 29 already evals what's in attrs.s3UploadOptions
.
Moreover, there seems to be an issue with the folder
parameter when used with targetFilename
: even when present, this parameter is silently ignored. You can indeed see where the issue comes from at the same line as previously 75:
var key = opts.targetFilename ? scope.$eval(opts.targetFilename) : opts.folder + (new Date()) ...
At this line, the folder
param is only used whenever no targetFilename
is provided (the default case).
If these two are actual bugs, and if you are interested in a PR, I can create one.
At last, your README
says npm install ng-s3upload
is a way to get the library, but the module does not seem available on npm.
Best regards,
Alex
NB: I'm not an angular developer.
Hi, how do I retain the original file name? Although the docs say
targetFilename - An optional attribute for the target filename. if provided the file will be renamed to the provided value instead of having the file original filename.
it uses a random string for the file name as per https://github.com/asafdav/ng-s3upload/blob/master/src/ng-s3upload/directives/s3-upload.js#L73
Is this expected? I just want to retain the original filename in the S3 key. Thanks! :)
In the tutorial, you said we can use the template:
I tried, but the attribute does not work, if I changed the bucket="dfsdev" (which is my bucket name), the console report, https://undefined.s3.amazonaws.com/
hi
i integrated your uploader in my site. the upload function works fine.
but if i choose a file, the buttons doesn't change to replace file and if a start the upload, the progress bar is only grey with no progress.
the files are uploading into the bucket well. the post and the answer is correct.
but in the frontend, i dont have any changes (no success info and so on...)
any ideas?
thank you
julian
Hi,
I am trying to use the ruby server code as my system is based on ruby on rails4, but I am facing the problem of call the server side code in the angularjs directive.
Here is my code:
<%
def s3_access_token
render json: {
policy: s3_upload_policy,
signature: s3_upload_signature,
key: GLOBAL[:aws_key]
}
end
def s3_upload_policy
@policy ||= create_s3_upload_policy
end
def create_s3_upload_policy
Base64.encode64(
{
"expiration" => 1.hour.from_now.utc.xmlschema,
"conditions" => [
{ "bucket" => GLOBAL[:aws_bucket] },
[ "starts-with", "$key", "" ],
{ "acl" => "public-read" },
[ "starts-with", "$Content-Type", "" ],
[ "content-length-range", 0, 10 * 1024 * 1024 ]
]
}.to_json).gsub(/\n/,'')
end
def s3_upload_signature
Base64.encode64(OpenSSL::HMAC.digest(OpenSSL::Digest::Digest.new('sha1'), GLOBAL[:aws_secret], s3_upload_policy)).gsub("\n","")
end
%>
<script type="text/ng-template" id="fileUploadPanel.html">I'm trying to use ng-s3upload with jcrop, which stores the image as a data URI. It doesn't seem like ng-s3upload supports the data uri as an image source, since it looks for a file explicitly (file[0]) unless I'm just using it wrong (always possible).
Does it currently support data URIs, or could it?
Trying to use this with browserify and npm doesn't work because this is missing from package.json:
"main": "build/ng-s3upload.js",
<span
s3-upload bucket="'myBucketName"
ng-model="files.first"
s3-upload-options="{getOptionsUri: 'http://Path/To/Server/'}"
do-upload="true">
</span>
$scope.files ={
first : 'http://scotch.io/wp-content/themes/thirty/img/scotch-logo.png'
}
This is not working. I get name is undefined. Because there is no filename.name parameter for the image being returned.
So can, someone explain, how do I choose a local or a remote path to file url as the value to ng-model ?
Example : ng-model="../images/1.png"
Would like to provide a filename for the upload in the options. This way we can force one for our users.
Apparently there is no way to customize the text of the upload button (currently 'Select File'), would be nice to have an option for that (especially when you have i18n in mind)
Is there a way to extend this component so we can offer drag and drop feature to the user.
Additionally, can we extend this component to support multiple files to be dragged and dropped, and also add positions so we can tag it on the S3.
Finally, how can I use the events that are emitted to scale the image and upload this resized image to S3 after the large image has been uploaded?
I believe with those features, this component should kick ass and completely replace a server side widget that does the same.
I'll dig deeper this weekend on the code to contribute on one of these features.
Thanks
It will be awesome if the directive will support Multipart upload.
It's much faster and supports uploads of up to 5TB
hahaha just wanted to say thanks for making such an intuitive directive for what can sometimes be a nifty problem. I'll defs fork it and make it more customisable in the future!
Hi,
I've trying to use this directive for a while and now I'm stuck trying to set the remote url to a variable in my controller.
<div s3-upload bucket="'my-videos'" ng-model="video.url" s3-upload-options="{getOptionsUri: '/ws/config'}"></div>
After the upload a url appears by on a link called "Stored file" pointing to the correct URL but the ngModel is not set on my controller.
I've debugged the directive and suspected about the ngModel being passed to the post link funciotn of the directive, it doesn't seem to be the one I've set on the div above.
Would you guys be able to help me figure out how to get the generated url?
Thanks in advance.
Getting EntityTooLarge error back from s3 for files larger than 10MB.
Quick question—is it possible to upload the file only on a click event (e.g. via an ng-click function in an angular controller) rather than the automatic upload as is currently implemented?
Thanks
I made this change to get the bucket so it would get set:
var bucket = (scope.$eval(attrs.bucket)) ? scope.$eval(attrs.bucket) : attrs.bucket;
which is ~line# 177 in build/ng-s3upload.js
.
var bucket = scope.$eval(attrs.bucket);
The above was coming up with bucket
as being undefined.
This is in the compile
method belonging to the ngS3upload
directive.
Hi, sorry for asking the simple question, these days I am trying to use this module for uploading file to Amazon based on ruby on rails, but I am not quite sure how to use the ruby example code, could you provide an ruby on rails example, or some tutorial step by step? thanks so much!!!!
Hi,
While this component works great now, I think we need more flexibility in terms of the template.
Is there a way to customize it?, it looks this is hardcoded right now and it doesn't blend with custom designs, therefore the need to be able to manipulate it.
Thanks
Hello everyone !
I'm currently trying to setup a direct upload from angular-file-upload to Amazon S3 bucket.
The upload process works fine, ex: If I upload an image of 3MB, the image is correctly transferred on my Amazon S3 bucket (located in Francfort btw, using the new AWS V4 signature)
The issue is the following one: The uploaded files cannot be opened and when I try to "cat" to see the binary content of the file, there are 3 lines added:
------WebKitFormBoundaryfOtaE6TQBF0hzBnw
Content-Disposition: form-data; name="file"; filename="01_-_Rock_Or_Bust.mp3"
Content-Type: audio/mp3
For each uploaded file, there is this "webkitformboundary" stuff added inside my file's binary content which is the reason of my issue I guess.
Does anyone know how to solve it?
I have a Node.js server that is basically generating pre-signed url and my app using this plugin to do the upload to S3.
I've been looking to solve this with my team for 24 hours now but no clue at moment.
Any ideas?
Best regards,
Another attribute could be "accept" to limit file types.
I'm trying to integrate my frontend with S3 and thus I've decided to use this directive to help.
I have coded the config as instructed in the README and something like this is being returned:
{
"policy":"eyJleHBpcmF0aW9uIjogIjI...sIDQxOTQzMDQwXV19",
"signature":"4eIITW8....m6fp0=",
"key":"4wv9VESY....pKeAkCyY"
}
Before applying the encryption my policy was:
{
"expiration":"2020-12-01T12:00:00.000Z",
"conditions":[
{
"bucket":"defina-se-videos"
},
[
"starts-with",
"$key",
""
],
{
"acl":"private"
},
[
"starts-with",
"$Content-Type",
"videos/"
],
[
"content-length-range",
0,
41943040
]
]
}
But when I run the html with the following configuration, I see a pre-flight request being made and nothing else happens:
I'm selecting a file that fits on the content length I've configured and I have also tried changing acl, adding a prefix, etc..
Do you have any tip to help me figure out what is happening?
Thanks in advance!
I think that duplication of bucket name on the angular side is not needed.
It gets pretty messy when we have staging and production environment and need to be in sync with server side configuration.
When passing a name through targetFilename
it might be helpful to append the correct file extension or use some other placeholders. I'll attach a PR with an example.
Examples:
%uploader.folder%file01%file.ext%
%uploader.folder%%file.date%%file.name%%file.ext%
How to call s3-upload from controller code?
You need to add a main property to bower.json for it to be recognized properly by the grunt service bowerInstall
First thanks for providing this cool piece of software!
I encounter the following problem:
If I print the value of bucket (assigned at line 40 in https://github.com/asafdav/ng-s3upload/blob/v0.1.2/src/ng-s3upload/directives/s3-upload.js) to the console, it is -1. After changing
var bucket = scope.$eval(attrs.bucket);
to
var bucket = attrs.bucket;
the HTML template looks like:
<div id="uploader" s3-upload bucket="{{env.s3Bucket}}" ng-model="files.first" s3-upload-options="{{s3options}}" do-upload="performUpload"></div>
whereby env holds some environment variables.
I get the right value. Is it a bug? Thanks for any hints/suggestions.
Versions:
Getting a 404 attempting to npm install ng-s3upload
On the documentation it indicates that YYY - HMAC and sha of your private key
but in the example it looks like something different going on. ruby Base64.encode64(OpenSSL::HMAC.digest(OpenSSL::Digest::Digest.new('sha1'), GLOBAL[:aws_secret], s3_upload_policy)).gsub("\n","")
. My interpretation of this is that HMAC digest should be for both the secret key and the policy and that the result of that should be Base64 encoded. Is that right? This is how I'm generating the policy:
var limit = 10 * 1024 * 1024;
var policy = {
"expiration": " <period>PT1H</period> ",
"conditions": [
{
"bucket": "curioso-uploads"
},
[
"starts-with",
"AKIAJL64SWZSQX2UXMA",
""
],
{
"acl": "public-read"
},
[
"starts-with",
"multipart/form-data",
""
],
[
"content-length-range",
0,
limit
]
]
};
this.policy = Base64.encode(JSON.stringify(policy));
this.signature = Base64.encode("f0513f710e328568ddfdsffsfce5d4d"); // I calculated this using bash as demonstrate in the following lines
echo -n "{\"expiration\":\" <period>PT1H</period> \",\"conditions\":[{\"bucket\":\"curioso-uploads\"},[\"starts-with\",\"AKIAJL64SWZSQX2UXMA\",\"\"],{\"acl\":\"public-read\"},[\"starts-with\",\"multipart/form-data\",\"\"],[\"content-length-range\",0,10485760]]}" | openssl dgst -sha1 -hmac "myprivatekey"
Using it with angular 1.2.15. Once I include it as a dependency, it just throws an error.
Hey,
I am getting the following error when the request goes for S3.
<?xml version="1.0" encoding="UTF-8"?>
<Error><Code>AccessDenied</Code><Message>Invalid according to Policy: Policy Condition failed: ["starts-with", "$Content-Length", ""]</Message>
<RequestId>12F4B56163EF2740</RequestId>
<HostId>SHiiZPupIS+0JxFHt2Jj2ksgis/X6cJzUIKeriLUOqtjKRBCZ0jx09bN9HUgLa7F</HostId>
</Error>
The code that I am using is as follows.
div(s3-upload bucket="'BUCKET" dynamic-name="field" ng-model="field.value" s3-upload-options="{getOptionsUri: '/s3options', folder: 'images/'}")
On the server I am using a library to generate the policy. Policy Generator
app.get('/s3options', function(req, res) {
var p = policy({
secret: 'FhfMGu32+hqnwtIpgT4WSNlE3ieyN9Vn8bAr+k',
length: 10 * 1024 * 1024,
bucket: 'tfiapp',
key: 'AKIAIDFSRY33SEKOFMBA',
expires: new Date(Date.now() + 60000),
acl: 'public-read',
type: ""
});
p.key = "AKIAIDFSRY33SEKOFMBA"; console.log("Key:" + p.key);
res.send(p);
});
It'd be nice to be able to feed a formatted filename to the directive via options.
Here is my code
My index.html
<html>
<head>
<title>UPLOAD</title>
<script src="/app/ajs/common/scripts/common/angular.min.js"></script>
<script src="plugins/ng-s3upload.js"></script>
<script src="s3.js"></script>
</head>
<body ng-app="amaup">
<div ng-controller="docCtrl">
<input name="file" type="file">
<div s3-upload bucket="kapptivo" ng-model="file"
s3-upload-options="{getOptionsUri: s3OptionsUri}">
</div>
</div>
</body>
</html>
here is my script file
angular.module('amaup',['ngS3upload']).
controller('docCtrl', ['$scope', function($scope){
alert("docCtrl invoked");
}]);
Please give the demo of ngS3Upload.
Can you add any additional headers to the request like Cache-Control easily? I can't figure out how.
Thanks
Hi,
I'm trying to use this module, but the request payload duplicates the content-type.
Not sure where this is hapenning, but the error is the one I see on the title.
AccessDeniedInvalid according to Policy: Extra input fields: content-type xxxxx
This is the request payload, any hints.
------WebKitFormBoundarywrG3WQbImsw3CmIS
Content-Disposition: form-data; name="key"
1233000928661-8file.jpeg
------WebKitFormBoundaryxxxx
Content-Disposition: form-data; name="acl"
public-read
------WebKitFormBoundaryxxxx
Content-Disposition: form-data; name="Content-Type"
image/jpeg
------WebKitFormBoundaryxxxx
Content-Disposition: form-data; name="AWSAccessKeyId"
KeyId...
------WebKitFormBoundarywrxxxx
Content-Disposition: form-data; name="policy"
encoded....
------WebKitFormBoundarywrxxxx
Content-Disposition: form-data; name="signature"
signature.....
------WebKitFormBoundaryxxxx
Content-Disposition: form-data; name="file"; filename="file.jpeg"
Content-Type: image/jpeg
CORS is the same as iin the example
My endpoint is built using aws php sdk
Thanks
Hello, I understand the concept of the button, which allow you to replace the file, however it does not seem to work and does not have any implementation in the code.
Can you explain further of how to make it work?
Thank you
Hi I've installed ng-s3upload via bower and I am getting a 404:
http://myUrl.dev/theme/bootstrap2.html 404 (Not Found)
I have also tried to use a custom path
app.config(function(ngS3Config) {
ngS3Config.theme = '/path/to/button.html';
});
but it is simply pre-pending 'theme/' to the path resulting in another 404, probably the result of this function:
templateUrl: function(elm, attrs) {
var theme = attrs.theme || ngS3Config.theme;
return 'theme/' + theme + '.html';
}
Have any ideas?
Right now it is fixed at 1.0.7.
If there is no reason, please change it to something like this:
{
"name": "ng-s3upload",
"version": "0.0.4",
"main": "build/ng-s3upload.js",
"dependencies": {
"angular": ">= 1.0.7",
"angular-sanitize": ">= 1.0.7"
},
"devDependencies": {
"angular-mocks": ">= 1.0.7",
"angular-scenario": ">= 1.0.7"
}
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.