i'm getting a 400 bad request error when trying to upload to cloudinary with the following code:
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': application/x-www-form-urlencoded,
'X-Requested-With': 'XMLHttpRequest'
}
})
.success(function (cloudinaryResponse) {
// do stuff with cloudinary response
// cloudinaryResponse = { public_id: ..., etc. }
})
.error(function (reponse) {
});
What am I missing? Is it possible to do a Cloudinary direct upload?
Related
I am trying to convert the below code which is using request module to axios module to send the POST request.
request module code:
const imageFile = fs.createReadStream('image.jpeg');
const imgName = "image" + ".jpeg";
var options = {
'method': 'POST',
'url': url,
'headers': {
'Content-Type': 'application/json',
'Cache-Control': 'no-cache',
'Accept': 'application/json'
},
formData: {
'image': {
'value': imageFile,
'options': {
'filename': imgName,
'contentType': null
}
}
}
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log("SUCCESS");
});
The above code works fine and the image is posted successfully with the request module. But when I convert the same to axios, I am getting a 500 Error. (AxiosError: Request failed with status code 500)
axios module code:
const FormData = require('form-data')
const imageFile = fs.createReadStream('image.jpeg');
const imgName = "image" + ".jpeg";
const bodyFormData = new FormData();
bodyFormData.append("image['value']", imageFile);
bodyFormData.append("image['options']['filename']", imgName)
// bodyFormData.append("image['options']['contentType']", null)
console.log(bodyFormData)
const formHeaders = bodyFormData.getHeaders();
axios.post(url, bodyFormData, {
headers: {
...formHeaders,
'Cache-Control': 'no-cache',
'Accept': 'application/json',
}
}).then(function (response) {
console.log('SUCCESS');
}).catch(function (error) {
throw new Error(error);
});
Can anyone find out what I am doing wrong here?
Is there any other way to post the image using axios other than using form-data?
See the documentation for FormData#append(). You can provide extra data like the file name as the 3rd options parameter
const bodyFormData = new FormData();
// Pass filename as a string
bodyFormData.append("image", imageFile, imgName);
// or to specify more meta-data, pass an object
bodyFormData.append("image", imageFile, {
filename: imgName,
contentType: "image/jpeg",
});
axios.post(url, bodyFormData, {
headers: {
Accept: "application/json",
"Cache-Control": "no-cache",
...bodyFormData.getHeaders(),
},
});
Under the hood, request() does something very similar with the exact same form-data library. See request.js
i need to upload video to bunny stream :bunny docs
i convert file to base64 as thy do here: upload file: BODY PARAMS
if you select js axios as LANGUAGE you'll see the data value set in base64
and this is my code:
function UploadVideo(e){
const data = new FormData();
let file = e.target.files[0];
let video;
const toBase64 = file => new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => resolve(reader.result);
reader.onerror = error => reject(error);
});
async function Main() {
video = await toBase64(file);
}
Main();
const c_options = {
method: 'POST',
url: 'https://video.bunnycdn.com/library/49034/videos',
headers: {
Accept: 'application/json',
'Content-Type': 'application/*+json',
AccessKey: ''
},
data: '{"title":"test"}'
};
axios.request(c_options).then(function (c_response) {
//upload start
const u_options = {
method: 'PUT',
url: `https://video.bunnycdn.com/library/49034/videos/${c_response.data.guid}`,
headers: {
Accept: 'application/json',
AccessKey: ''
},
data: video,
};
axios.request(u_options).then(function (u_response) {
//post url to php
console.log(u_response.data);
}).catch(function (error) {
console.error(error);
});
//upload end
console.log(c_response.data);
}).catch(function (error) {
console.error(error);
});
}
but it return status code 400
The 400 error text: "Failed to read the request form. Form key length limit 2048 exceeded."
how can i do that?
The error is telling that a key is too long.
Your data property is meant to be an object, because axios default Content-Type (which you have omitted) is application/x-www-form-urlencoded.
If you want to send the file, then you need to set the Content-Type in you header to Content-Type: application/octet-stream, i.e. your header object should be
headers: {
Accept: 'application/json',
AccessKey: '',
Content-Type: 'application/octet-stream'
},
This shown in the javascript example on the bunny.net page you link to.
I am downloading some file with $http which is calling java rest API, it responds in buffered array. I have to persist the download even if the browser reloaded. I am not sure whether it is possible or not within the client side itself.
Here is my code :
$http({
url : downloadUrl,
method : 'POST',
data : {filePath : path},
cache: true,
headers : {
'Content-type' : 'application/json',
'Accept': 'application/zip'
},
eventHandlers: {
progress: function (e) {
console.log('Progress :'+((e.loaded /
itemSelected.fileSize) * 100));
}
},
responseType : 'arraybuffer'
}).then(function (res) {
var blob = new Blob([res.data], {type:"application/octet-
stream"});
var filename = test.zip;
// using filesaver to download the file from blob
FileSaver.saveAs(blob, filename);
}, function (err) {
console.log(err);
});
I have a front end Canvas that I transform into a png file that I need to POST to a third party vendor's api. It passes back to node as a base64 file and I decode it, but when I attempt the upload, it gives me the following error:
Problem processing POST request: no Content-Type specified
However, I am clearly specifying the content type in my POST call. My end goal is to upload the file to my vendor's API.
Here are the key front end aspects:
var canvasImage = document.getElementById("c");
var img = canvas.toDataURL({
multiplier: canvasMultiplier
});
var fileTime = Date.now();
var myFileName = $scope.productCode + fileTime;
$scope.filenameForVendor = myFileName;
var filename = $scope.filenameForVendor;
$http.post('/postVendor', { filename: filename, file: img }).success(function (data) {
console.log("Uploaded to Vendor");
Here is the backend POST:
app.post('/postVendor', function (req, res, next) {
var filename = req.body.filename;
var file = req.body.file;
fileBuffer = decodeBase64Image(file);
request({
url: "http://myvendorapi/ws/endpoint",
method: "POST",
headers: {
'contentType': fileBuffer.type
},
body: fileBuffer.data
}, function (error, response, body) {
console.log(response);
});
})
// Decode file for upload
function decodeBase64Image(dataString) {
var matches = dataString.match(/^data:([A-Za-z-+\/]+);base64,(.+)$/),
response = {};
if (matches.length !== 3) {
return new Error('Invalid input string');
}
response.type = matches[1];
response.data = new Buffer(matches[2], 'base64');
return response;
}
I can POST using AJAX on the front end, but because of CORS and the vendor blocking all but server side calls to the endpoints (and they don't have JSONP), I can't use this. They are allowing my IP through for testing purposes so only I can make this work from my machine:
var send = function (blob) {
var fileTime = Date.now();
var myFileName = $scope.productCode + fileTime;
$scope.filenameForVendor = myFileName;
var filename = $scope.filenameForVendor;
var formdata = new FormData();
formdata.append('File1', blob, filename);
$.ajax({
url: 'http://myvendorapi/ws/endpoint',
type: "POST",
data: formdata,
mimeType: "multipart/form-data",
processData: false,
contentType: false,
crossDomain: true,
success: function (result) {
console.log("Upload to Vendor complete!");
// rest of code here/including error close out
}
var bytes = atob(dataURL.split(',')[1])
var arr = new Uint8Array(bytes.length);
for (var i = 0; i < bytes.length; i++) {
arr[i] = bytes.charCodeAt(i);
}
send(new Blob([arr], { type: 'image/png' }));
Update:
I realized that contentType should be 'content-type'. When I did this, it creates an error of no boundary specified as I am trying multipart-form data (which I did all wrong). How can I pass formData to Node for uploading?
Update 2:
Per the advice offered, I tried using multer but am getting an ReferenceError: XMLHttpRequest is not defined.
Client side:
var fileTime = Date.now();
var myFileName = $scope.productCode + fileTime;
$scope.filenameForVendor = myFileName;
var filename = $scope.filenameForVendor;
var formdata = new FormData();
formdata.append('File1', blob, filename);
$http.post('/postVendor', formdata, { transformRequest: angular.identity, headers: { 'Content-Type': undefined } }).success(function (data) {
Server side:
app.post('/postVendor', function (req, res, next) {
var request = new XMLHttpRequest();
request.open("POST", "http://myvendorapi.net/ws/endpoint");
request.send(formData);
})
Why do you base64 encode the file?
You can upload raw file to your Node using FormData and you will not have to decode anything.
Front end
...
var request = new XMLHttpRequest();
request.open('POST', 'http://node.js/method');
request.send(formData); // vanilla
--- or ---
...
$http.post('http://node.js/method', formData, {
transformRequest: angular.identity,
headers: {'Content-Type': undefined}
}); // angular
Back end
Just install request.
...
var request = require('request');
app.post('/method', function (req, res, next) {
// if you just want to push request you don't need to parse anything
req.pipe(request('http://vendor.net')).pipe(res);
}) // express
I am trying to upload a file with AngularJS. This is my code:
HTML
<input type="file" file-model="myFile"/>
<button ng-click="uploadFile()">upload me</button>
JavaScript
$scope.uploadFile = function(){
var file = $scope.myFile;
var uploadUrl = "http://admin.localhost/images/patanjali/";
VariantService.uploadFileToUrl(file, uploadUrl);
};
VariantService.uploadFileToUrl = function(file, uploadUrl){
var fd = new FormData();
fd.append('file', file);
$http.post(uploadUrl, fd, {
transformRequest: angular.identity,
headers: {'Content-Type': undefined}
})
.success(function(){
alert ('success');
})
.error(function(){
});
}
Although I can see the ('success') alert in my service, the file is not saving in the location provided in controller.
Can someone help me? What is missing?
It looks like you're using code from this jfiddle for your app:
myApp.service('fileUpload', ['$http', function ($http) {
this.uploadFileToUrl = function(file, uploadUrl){
var fd = new FormData();
fd.append('file', file);
$http.post(uploadUrl, fd, {
transformRequest: angular.identity,
headers: {'Content-Type': undefined}
})
.success(function(){
})
.error(function(){
});
}
}]);
While properly configured, this is only for posting data from the client side; the server also needs to be configured to accept/save the data. How you do this depends on your back-end tech stack.
I had same issue. I tried following code and my problem was solved.
var req = {
method: 'POST',
url: url,
headers: {
'Content-Type': "application/json",
},
data: data,
transformRequest: function(data, headersGetter) {
var formData = new FormData();
angular.forEach(data, function(value, key) {
formData.append(key, value);
});
var headers = headersGetter();
delete headers['Content-Type'];
return formData;
}
}
$http(req)
.success(function(response) {
$scope.Models = response;
})
.error(function(data, status, headers, config) {
// called asynchronously if an error occurs
// or server returns response with an error status.
alert(data);
});
$scope.setFiles = function (element) {
$scope.$apply(function (scope) {
$scope.files = [];
for (var i = 0; i < element.files.length; i++) {
scope.files.push(element.files[i])
}
});
};
$scope.uploadFile = function() {
var fd = new FormData();
for (var i in $scope.files) {
fd.append('file', $scope.files[i])
}
$http.post('http://admin.localhost/images/patanjali', fd, {
transformRequest: angular.identity,
headers: {
'Content-Type': undefined
}
})
.then(function successCallback(response) {
}, function errorCallback(response) {
});
};
<script src='https://ajax.googleapis.com/ajax/libs/angularjs/1.6.6/angular.min.js'></script>
<input type="file" valid-file ng-model-instant id="fileToUpload" onchange="angular.element(this).scope().setFiles(this)" />
<button ng-click="uploadFile()">Upload me</button>
You can use AngularJs modules for file uploader.The modules are very useful and very comfortable.
1) https://github.com/nervgh/angular-file-upload
2) https://github.com/danialfarid/ng-file-upload