I can't upload multiple images to Amazon S3 using Sails.js - javascript

I'm trying to upload multiple images to Amazon S3 and using Sails.js framework.This is my code:
Fotos.ejs (Is the view for uploading photos):
<form enctype="multipart/form-data" id="frmFotos">
<input id="fotos" name="fotos" type="file">
<button type="submit" id="btnUpload">Upload</button>
</form>
Fotos.js (Ajax call for upload)
$('#btnUpload').on('click',function(e){
e.preventDefault();
var formData=new FormData();
formData.append("fotos",$("#fotos")[0].files);
$.ajax({
url:"/upload",
data: formData,
processData: false,
contentType: false,
type: 'POST',
success: function(data){
console.log(data);
}
});
})
FotoController.js (Controller in Sails.js where I'm using skipper-s3 to upload files)
module.exports = {
upload:function(req,res){
var aws={
adapter:require("skipper-s3"),
bucket:"mybucket",
key:"mykey",
secret:"mysecret"
};
req.file("fotos").upload({aws},function whenDone(error,fotos){
if(error)
{
console.log(error);
} else{
fotos.forEach(function(foto){
console.log(foto);
});
}
});
}
}
I think that there is an additional task because I can't see my images in the bucket in S3. I test the code with a single image and this works fine.

You have to specify the region in which your bucket belongs. For instance:
var aws = {
...
region: 'us-west-2'
...
}
Your region may be located elsewhere than US West 2. In which case, either create a new bucket in US West 2, or find your region's code (e.g.: us-west-1, us-east-1).

Related

how to upload image from local disk to the web using imgur api?

I want to building a file uploader app that would allow users to upload images from the local disk to the web , I search on web and find this link to use imgur api this is url
but it did not work , I put the code in jsfiddle.net but also not work this is the link of jsfiddle
this is the code :
<form id="imgur">
<input type="file" class="imgur" accept="image/*" data-max-size="5000"/>
</form>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script>
$("document").ready(function() {
$('input[type=file]').on("change", function() {
var $files = $(this).get(0).files;
if ($files.length) {
// Reject big files
if ($files[0].size > $(this).data("max-size") * 1024) {
console.log("Please select a smaller file");
return false;
}
// Begin file upload
console.log("Uploading file to Imgur..");
// Replace ctrlq with your own API key
var apiUrl = 'https://api.imgur.com/3/image';
var apiKey = 'ctrlq';
var settings = {
async: false,
crossDomain: true,
processData: false,
contentType: false,
type: 'POST',
url: apiUrl,
headers: {
Authorization: 'Client-ID ' + apiKey,
Accept: 'application/json'
},
mimeType: 'multipart/form-data'
};
var formData = new FormData();
formData.append("image", $files[0]);
settings.data = formData;
// Response contains stringified JSON
// Image URL available at response.data.link
$.ajax(settings).done(function(response) {
console.log(response);
});
}
});
});
<script>
so what wrong can any body help ?
EDIT :
I register and get the key client_id:5b9144f6bcc473e and I put the apiKey=5b9144f6bcc473e but still did not work any help

Can't collate all the files sent to s3 in a batch

I have a React + Rails chat application and I want to add attachments to the same.
I'm using React Dropzone component to do attach images. Every time an image successfully gets added to the dropzone, it calls the attachToS3 function and posts that image to S3 as well. On successful posting it sets the state of new_message_content as the url of the file.
Once, the user has uploaded all the files, they can click on send which inserts the new_message_content as a new message in the conversation.
Since, I'm allowing users to add multiple files at the same time therefore my state only contains the url of the last uploaded file and not an array of all the URL's.
My dropzone is being rendered as follows:
renderFileDropzone() {
let componentConfig = { postUrl: 'random_url'},
djsConfig = { autoProcessQueue: true, addRemoveLinks: true },
eventHandlers = { addedfile: this.attachToS3.bind(this) };
return(
<div>
<div className="dashboard-modal">
<div className="dashboard-modal-content">
<div className="dashboard-modal-header">
<h5>Send files to {this.state.counterparty.name}</h5>
<span onClick={this.closeDropzone.bind(this)} className="icon-cancel modal-close"></span>
</div>
<form>
<div className="dashboard-modal-body">
<DropzoneComponent config={componentConfig} eventHandlers = {eventHandlers} djsConfig = {djsConfig} />
<button onClick={this.sendMessage.bind(this)} type="submit" className="btn btn-secondary">Send Files</button>
</div>
</form>
</div>
</div>
<div className="modal-bg bg-transparent-black"></div>
</div>
)
}
Now, my Dropzone component allows multiple file uploads at the same time but since I can't do a direct upload to Amazon S3 of multiple files at the same time so I pass the files, one by one.
attachToS3 function
attachToS3(file) {
let self = this;
API.get('user/s3_post_attachment', {filename : file.name}, function (s3_params) {
let formData = new FormData();
Object.keys(s3_params.formdata).forEach(function(k) {
formData.append(k, s3_params.formdata[k]);
});
formData.append('file', file);
$.ajax({
url: s3_params.url,
type: 'POST',
data: formData,
async: true,
dataType: "xml",
success: function (data) {
let file_url = $(data).find('Location').html();
self.setState({ new_message_content : file_url });
},
cache: false,
contentType: false,
processData: false
});
});
}
I tried adding a localStorage to my attachToS3 function, like this:
var url_array = JSON.parse(localStorage.getItem('allFiles'));
if (url_array == null) url_array = [];
var url = {
'url' : file_url
};
localStorage.setItem('url', JSON.stringify(url));
url_array.push(url);
localStorage.setItem('allURL', JSON.stringify(url_array));
But it's not working and I'm getting an error url_array.push is not a function.
Is there any way to get all the file url's in an array?

Upload files to Dropbox using a Dropbox Core API in Javascript

I am working on a simple chrome-extension that needs to upload files to the user's dropbox folder. I am using the simple AJAX requests as mentioned below to upload files, however it works for files with extensions such as .txt, .json, .c, etc i.e. files whose mime type is of type text/plain or similar type but all other file types such as pdfs, image files etc get corrupted and produce blank contents. What am I missing in uploading the files the correct way.
function startUpload()
{
var folderPath = $(this).closest('tr').attr('path')+'/';
var file = $("#upload_file")[0].files[0];
if (!file){
alert ("No file selected to upload.");
return false;
}
var reader = new FileReader();
reader.readAsText(file, "UTF-8");
reader.onload = function (evt) {
uploadFile(folderPath+file.name,evt.target.result,file.size,file.type);
}
}
//function to upload file to folder
function uploadFile(filepath,data,contentLength,contentType){
var url = "https://api-content.dropbox.com/1/files_put/auto"+filepath;
var headers = {
Authorization: 'Bearer ' + getAccessToken(),
contentLength: contentLength,
};
var args = {
url: url,
headers: headers,
crossDomain: true,
crossOrigin: true,
type: 'PUT',
contentType: contentType,
data : data,
dataType: 'json',
success: function(data)
{
getMetadata(filepath.substring(0,filepath.lastIndexOf('/')),createFolderViews);
},
error: function(jqXHR)
{
console.log(jqXHR);
}
};
$.ajax(args);
}
I believe the issue is reader.readAsTextFile(file, "UTF-8"). If the file isn't a text file, this will misinterpret the contents. I think you want reader.readAsBinaryString or reader.readAsArrayBuffer. (I haven't tested it myself.)
EDIT
After testing this myself, I found that readAsArrayBuffer is what you need, but you also need to add processData: false as an option to $.ajax to prevent jQuery from trying to convert the data to fields in a form submission.
Also be sure to use dataType: 'json' to properly parse the response from the server.

Upload image to facebook from input file

So, i'm trying top upload a simple image to facebook using the graph api.
The file is uploaded by an input type file
var file= $("#imagenesUpload")[0].files[0];
var formData = new FormData();
formData.append("source", file);
FB.api("/me/photos", "POST", formData,
function (response) {
if (response) {
console.log(response);
}
}
);
But i'm always getting a (#324) Requires upload file
Also tried this with the same result
var file= $("#imagenesUpload")[0].files[0];
FB.api("/me/photos", "POST", {"source":file},
function (response) {
if (response) {
console.log(response);
}
}
);
On the official Facebook Developers site there is a post explaining how images should be set. Here is the link: https://developers.facebook.com/blog/post/498/
(Check out Scenario 2)

File Upload without Form

Without using any forms whatsoever, can I just send a file/files from <input type="file"> to 'upload.php' using POST method using jQuery. The input tag is not inside any form tag. It stands individually. So I don't want to use jQuery plugins like 'ajaxForm' or 'ajaxSubmit'.
You can use FormData to submit your data by a POST request. Here is a simple example:
var myFormData = new FormData();
myFormData.append('pictureFile', pictureInput.files[0]);
$.ajax({
url: 'upload.php',
type: 'POST',
processData: false, // important
contentType: false, // important
dataType : 'json',
data: myFormData
});
You don't have to use a form to make an ajax request, as long as you know your request setting (like url, method and parameters data).
All answers here are still using the FormData API. It is like a "multipart/form-data" upload without a form. You can also upload the file directly as content inside the body of the POST request using xmlHttpRequest like this:
var xmlHttpRequest = new XMLHttpRequest();
var file = ...file handle...
var fileName = ...file name...
var target = ...target...
var mimeType = ...mime type...
xmlHttpRequest.open('POST', target, true);
xmlHttpRequest.setRequestHeader('Content-Type', mimeType);
xmlHttpRequest.setRequestHeader('Content-Disposition', 'attachment; filename="' + fileName + '"');
xmlHttpRequest.send(file);
Content-Type and Content-Disposition headers are used for explaining what we are sending (mime-type and file name).
I posted similar answer also here.
UPDATE (January 2023):
You can also use the Fetch API to upload a file directly as binary content (as also was suggested in the comments).
const file = ...file handle...
const fileName = ...file name...
const target = ...target...
const mimeType = ...mime type...
const promise = fetch(target, {
method: 'POST',
body: file,
headers: {
'Content-Type': mimeType,
'Content-Disposition', `attachment; filename="${fileName}"`,
},
},
});
promise.then(
(response) => { /*...do something with response*/ },
(error) => { /*...handle error*/ },
);
See also a related question here: https://stackoverflow.com/a/48568899/1697459
Step 1: Create HTML Page where to place the HTML Code.
Step 2: In the HTML Code Page Bottom(footer)Create Javascript: and put Jquery Code in Script tag.
Step 3: Create PHP File and php code copy past. after Jquery Code in $.ajax Code url apply which one on your php file name.
JS
//$(document).on("change", "#avatar", function() { // If you want to upload without a submit button
$(document).on("click", "#upload", function() {
var file_data = $("#avatar").prop("files")[0]; // Getting the properties of file from file field
var form_data = new FormData(); // Creating object of FormData class
form_data.append("file", file_data) // Appending parameter named file with properties of file_field to form_data
form_data.append("user_id", 123) // Adding extra parameters to form_data
$.ajax({
url: "/upload_avatar", // Upload Script
dataType: 'script',
cache: false,
contentType: false,
processData: false,
data: form_data, // Setting the data attribute of ajax with file_data
type: 'post',
success: function(data) {
// Do something after Ajax completes
}
});
});
HTML
<input id="avatar" type="file" name="avatar" />
<button id="upload" value="Upload" />
Php
print_r($_FILES);
print_r($_POST);
Basing on this tutorial, here a very basic way to do that:
$('your_trigger_element_selector').on('click', function(){
var data = new FormData();
data.append('input_file_name', $('your_file_input_selector').prop('files')[0]);
// append other variables to data if you want: data.append('field_name_x', field_value_x);
$.ajax({
type: 'POST',
processData: false, // important
contentType: false, // important
data: data,
url: your_ajax_path,
dataType : 'json',
// in PHP you can call and process file in the same way as if it was submitted from a form:
// $_FILES['input_file_name']
success: function(jsonData){
...
}
...
});
});
Don't forget to add proper error handling
Try this puglin simpleUpload, no need form
Html:
<input type="file" name="arquivo" id="simpleUpload" multiple >
<button type="button" id="enviar">Enviar</button>
Javascript:
$('#simpleUpload').simpleUpload({
url: 'upload.php',
trigger: '#enviar',
success: function(data){
alert('Envio com sucesso');
}
});
A non-jquery (React) version:
JS:
function fileInputUpload(e){
let formData = new FormData();
formData.append(e.target.name, e.target.files[0]);
let response = await fetch('/api/upload', {
method: 'POST',
body: formData
});
let result = await response.json();
console.log(result.message);
}
HTML/JSX:
<input type='file' name='fileInput' onChange={(e) => this.fileInput(e)} />
You might not want to use onChange, but you can attach the uploading part to any another function.
Sorry for being that guy but AngularJS offers a simple and elegant solution.
Here is the code I use:
ngApp.controller('ngController', ['$upload',
function($upload) {
$scope.Upload = function($files, index) {
for (var i = 0; i < $files.length; i++) {
var file = $files[i];
$scope.upload = $upload.upload({
file: file,
url: '/File/Upload',
data: {
id: 1 //some data you want to send along with the file,
name: 'ABC' //some data you want to send along with the file,
},
}).progress(function(evt) {
}).success(function(data, status, headers, config) {
alert('Upload done');
}
})
.error(function(message) {
alert('Upload failed');
});
}
};
}]);
.Hidden {
display: none
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div data-ng-controller="ngController">
<input type="button" value="Browse" onclick="$(this).next().click();" />
<input type="file" ng-file-select="Upload($files, 1)" class="Hidden" />
</div>
On the server side I have an MVC controller with an action the saves the files uploaded found in the Request.Files collection and returning a JsonResult.
If you use AngularJS try this out, if you don't... sorry mate :-)

Categories

Resources