I want to send some attributes and a file to a Node JS application with multipart/form-data.
Client HTML Form:
<input id="picName" name="picName" class="form-control" placeholder="PicTitle..." style="border-radius: 1%; margin: 1%" type="name">
<form id="frmUploader" enctype="multipart/form-data" action="/post/picture/" method="post">
<input id="file" type="file" name="picUploader" multiple /><br>
<input class="btn btn-md btn-success" type="submit" name="submit" id="btnSubmit" value="Upload" /><br>
</form>
Client JS:
$('#frmUploader').submit(function () {
var username = localStorage.getItem("userName");
var categoryName = $( "#categoryAddPic option:selected").text();
var picTitle = $('#picName').val();
var picture = $('input[name="picUploader"]').get(0).files[0];
var formData = new FormData();
formData.append('picture', picture);
formData.append('username', username);
formData.append('categoryName', categoryName);
formData.append('picTitle', picTitle);
$.ajax({
method: 'POST',
url: 'http://localhost:3000/post/picture',
data: formData,
headers:{
"Authorization": "bearer " + token
},success:function (respond) {
...
});
}
return false;
});
Now I want to save the data of the form in my Node application. If it is necessary to know too, I´m using multer for saving the file on the server.
Thanks for help.
PS: The node version is 4.8.3
Node JS:
app.post('/post/picture',function (req, res, next) {
var picName = req.body.picName;
var username = req.body.username;
var displayPic = req.body.displayPic;
var createdAt = moment();
var updatedAt = moment();
var categoryName = req.body.categoryName;
var picIdForCat = null;
try {
if (username) {
upload(req, res, function (err) {
if (err) {
return res.end("Something went wrong!");
}
//return res.end("File uploaded sucessfully!.");
picName = pictureSaveFormat;
var pictureCont = "./pictures/" + picName + ".jpg";
User.findOne({
where: {username: username}
}).then(function (user) {
var picture = {
picName: picName,
picture: pictureCont,
displayPic: null,
createdAt: createdAt,
updatedAt: updatedAt,
UserIdUser: user.idUser
};
Pictures.create(picture);
if (categoryName) {
Pictures.findOne({
where: {picName: picture.picName}
}).then(function (pic) {
picIdForCat = pic.idPic;
Category.findOne({
where: {categoryName: categoryName}
}).then(function (category) {
var catId = category.idCat;
var catForPic = {PictureIdPic: picIdForCat, CategoryIdCat: catId};
CategorieForPic.create(catForPic);
//res.redirect('localhost:3000/index.Admin.html');
res.status(200).json({message: "Picture from: " + username + " with name: " + picName + " created with " + category.categoryName + "."});
})
}).catch(function (req, res, err) {
res.status(500).json({message: "Error: Adding Category to pic", reason: err});
});
} else {
//res.redirect('localhost:3000/index.Admin.html');
res.status(200).json({message: "Picture from: " + username + " with name: " + picName + " created without a category."});
}
}).catch(next);
});
} else {
res.status(404).json({message: "Not found.", reason: "A required parameter is missing."});
}
}catch (err){
res.status(500).json({message: "Fatal Server error: ", reason: err});
}
});
When using a FormData object with jQuery.ajax, you have to set processData to false so that jQuery will not try to encode the FormData object and contentType to false so that jQuery will not set any content type headers. When FormData is used with ajax the proper content type header is generated for you.
$.ajax({
method: 'POST',
url: 'http://localhost:3000/post/picture',
data: formData,
processData: false,
contentType: false,
headers:{
"Authorization": "bearer " + token
},
success:function (respond) {
...
});
}
headers: {
"Content-Type": "multipart/form-data",
"Authorization": "bearer " + token
},
It was working on my side
Related
This is my post request from nodejs server
app.post('/api/users', urlencodedParser, function (req, res) {
if (!req.body) return res.sendStatus(400);
console.log(req.body);
var data = req.body;
db.collection('users').findOne({
username: data.username
}, (err, result) => {
if (result === null) {
db.collection('users').insertOne(data, function (err) {
if (err) throw err;
console.log("Record inserted!");
res.status(200).send("recordInserted");
})
} else {
console.log("Already exists");
res.status(500).send("userExists");
}
})
})
This is my ajax request
$('#signupForm').on('submit', function () {
var userData = {
fullName: $("#fullName").val(),
username: $("#username").val(),
password: $("#password").val(),
email: $("#email").val()
};
$.ajax({
type: "post",
data: userData,
dataType: "text",
url: "/api/users",
function (data, status) {
if(data== 'recordInserted'){
alert("Recors inserted");
console.log("Inserted \n" + data +"\n" + status);
}
else if(data == 'userExists') {
alert("User exists");
console.log(data + "\n " + status);
}
}
});
});
I cant send back the response to the ajax request and because of that the page doesn't reload or show an error if the user already exists
As a first order of business, the preferred way for awhile now to handle responses in AJAX has been to utilize deferred objects.
let request = $.ajax({url: 'google.com', type:'get'});
request.done(function(response){
// handle response
});
Beyond that, your back-end looks to be fine.
Although!
I would highly recommend changing how you go about error handling on the server-side. If the server throws an error, the client will be left hanging until they timeout. Its best to alert the client that an error has occurred, as well.
use of e.preventDefault(); method will stop the page from being reload. you can copy paste the code
$('#signupForm').on('submit', funfunction(e) {
e.preventDefault();
let userData = {
fullName: $("#fullName").val(),
username: $("#username").val(),
password: $("#password").val(),
email: $("#email").val()
};
$.ajax({
type: "post",
data: userData,
dataType: "text",
url: "/api/users",
function (data, status) {
if(data== 'recordInserted'){
alert("Recors inserted");
console.log("Inserted \n" + data +"\n" + status);
}
else if(data == 'userExists') {
alert("User exists");
console.log(data + "\n " + status);
}
}
});
});
In my node.js api I am trying to pass multiple values into the fields tracking and carrier , but I have been unsuccessful. I am able to do this with single values (1 tracking number for tracking and 1 carrier code for carrier), but not for multiple values. I feel like there should be a loop involve, but maybe I am incorrect in stating this. Any help would be greatly appreciated.
Index.html
<script>
function UserParams() {
console.log('UserParams')
var trackingNumber = ['123', '456'];
var carrierCode = ['usps', 'fedex'];
var url = '/api/tracking/retrieve/';
$.ajax({
type: 'GET',
url: url,
data: { tracking: trackingNumber, carrier: carrierCode },
dataType: 'json',
error: function (e) {
console.log('Error Message: ', e.message);
}
});
}
</script>
Controller.js
app.get("/api/tracking/retrieve", (req, res) => {
var carrier = req.query.carrier;
var tracking = req.query.tracking;
console.log('carrier array', carrier);
console.log('tracking array', tracking);
var options = {
method: "GET",
url: 'https://api.example.com/v1/tracking',
qs: { carrier_code: carrier, tracking_number: tracking },
headers:
{
'api-key': process.env.SECRET_KEY_SE,
'accept': 'application/json'
}
}
console.log("Url: ", req.url);
console.log("Query: ", req.query);
res.send("ok");
request(options, function (error, response, body) {
if (!error && response.statusCode == 200) {
console.log('BODY', body)
var trackingData = JSON.parse(body)
table = 'tracking_table';
col = [
'user_id',
'tracking_number',
'carrier_code',
];
val = [
user_id,
trackingData.tracking_number,
options.qs.carrier_code,
];
main.create(table, col, val, function (data) {
res.json({
id: data.insertId,
user_id: user_id,
tracking_number: data.tracking_number,
carrier_code: data.carrier_code,
});
})
}
})
})
Result in terminal:
carrier array [ 'usps', 'fedex' ]
tracking array [ '123', '456' ]
Url: /api/tracking/retrieve/?tracking%5B%5D=123&tracking%5B%5D=456&carrier%5B%5D=usps&carrier%5B%5D=fedex
Query: { tracking: [ '123', '456' ],
carrier: [ 'usps', 'fedex' ] }
Edit: Edited question to include further context.
Depending on what the backend is you can try simply using arrays for this purpose, e.g.
var tracking = ['9361289691090998780245','784644233438'];
var carrier = ['usps','fedex'];
options = {
method: "GET",
url: 'https://api.example.com/v1/tracking',
qs: { tracking_number: tracking, carrier_code: carrier },
headers:
{
'api-key': process.env.SECRET_KEY_SE,
'accept': 'application/json'
}
}
request(options, function (error, response, body) {
if (error) console.error("An error occurred: ", error);
console.log("body: ", body);
});
If this is served by Express, the query string will be parsed correctly, e.g.
app.get("/api/tracking/retrieve", (req, res) => {
console.log("Url: ", req.url);
console.log("Query: ", req.query);
res.send("ok");
});
This is what would be logged by Express;
Url: /api/tracking/retrieve?tracking_number%5B0%5D=9361289691090998780245&tracking_number%5B1%5D=784644233438&carrier_code%5B0%5D=usps&carrier_code%5B1%5D=fedex
Query: { tracking_number: [ '9361289691090998780245', '784644233438' ], carrier_code: [ 'usps', 'fedex' ] }
Of course it depends on the API provider, so it might be worth seeing if they have documentation on how parameters should be formatted.
Try to change string tracking & carrier to array with function split
app.get('/api/tracking/retrieve', function (req, res) {
options = {
method: "GET",
url: 'https://api.example.com/v1/tracking',
qs: { tracking_number: tracking.split(','), carrier_code: carrier.split(',') },
headers:
{
'api-key': process.env.SECRET_KEY_SE,
'accept': 'application/json'
}
}
request(options, function (error, response, body) {
})
});
In this code i am calling login API. and also using JSON to parse the data.when i am running this code on command prompt no output is there.what is wrong thing i am doing in my code and what is the right way to do that please help me.
--I supposed to see my output on command prompt--
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
var querystring = require('querystring');
var https = require('https');
var host = 'https://blahabc.com/api/login.json';
var username = 'xxxxx';
var password = '******';
var apiKey = '*****';
var sessionId = '1234567890';
function performRequest(endpoint, method, data, success) {
console.log("hello");
var dataString = JSON.stringify(data);
var headers = {};
if (method == 'POST') {
endpoint += '?' + querystring.stringify(data);
}
else {
headers = {
'Content-Type': 'application/json',
'Content-Length': dataString.length
};
}
var options = {
host: 'blahabc.com',
path: '/api/login',
method: 'POST',
// headers: headers
};
}
console.log("bye");
function login() {
performRequest('/api/login', 'POST', {
username: 'xxxxx',
password: '******',
api_key_id: '******'
},
function(data) {
console.log(data);
sessionId = data.result.id;
console.log('Logged in:', sessionId);
console.log("tring");
getCards();
});
console.log("hello");
}
function getCards() {
console.log("hello");
performRequest('/api/post_login' + deckId + '/cards', 'POST', {
session_id: '1234567890',
"_items_per_page": 100
}, function(data) {
console.log('Fetched ' + data.result.paging.total_items + ' cards');
});
}
login();
You aren't calling anything to make a request in your performRequest() function. You need to make a call to XMLHttpRequest to post the request to the server.
I am trying to post a video from the browser to an edge sing the below code
var url = "https://graph.facebook.com/v2.5/" + this.uid + "/videos" + "?access_token=" + token;
var formData = new FormData();
formData.append("source", file);
formData.append("access_token", token);
return $.ajax({
url: url,
contentType: false,
processData: false,
type : "POST",
data: formData
})
But it gives a 400 bad request error.The response is
{
"error": {
"message": "Bad signature",
"type": "OAuthException",
"code": 1,
"fbtrace_id": "FYc5192NtSs"
}
}
Can you please tell me what am I doing wrong ?
I made the following utility function
var makeApiRequest: function(accessToken, config, successCallback, errorCallback) {
var baseUrl = 'https://graph.facebook.com/v2.5/';
// parse config and defaults
var config = config || {},
url = config.url || 'me',
data = config.data || {},
method = config.method || 'GET';
config.url = baseUrl + url + '&access_token=' + accessToken;
// make the api request
$.ajax(config)
.done(function(data) {
if (!!successCallback) {
successCallback(data);
} else {
console.log(data);
}
}
).error(function(xhr) {
errorCallback(xhr);
});
}
Which can be called like this for a video.
makeApiRequest(
'<token>',
{
url: 'me/videos',
data: {file_url:'http://example.com/path/to/file.mp4', description: 'title'},
method: 'POST'
}, successCb, errorCb);
Please ensure you use a token which was acquired using v2.5 of the API. You need publish_actions, publish_pages (for pages) permission to post
Debug your access token here
I've been trying to connect to MailChimp 3.0 API through the JS function below:
var mailchimp_api_key = (api key as in my account);
var name = $('#name').val();
var email = $('#email').val();
if(name.indexOf(' ') != 0) {
var fname = name.substr(0, name.indexOf(' '));
var lname = name.substr(name.indexOf(' ') + 1);
} else {
fname = name;
}
var mailchimp = JSON.stringify({
email_address: email,
status: 'subscribed',
merge_fields: {
FNAME: fname,
LNAME: lname
}
});
$.ajax({
url: 'http://(my server in MC).api.mailchimp.com/3.0/lists/(list id)/members/',
type: 'POST',
data: mailchimp,
dataType: 'jsonp',
contentType: 'application/json; charset=utf-8',
error: function(res, text){
console.log('Err', res);
},
success: function(res){
console.log('Success', res);
},
beforeSend: function (xhr) {
xhr.setRequestHeader ("Authorization", "Basic " + btoa("api:" + mailchimp_api_key))
}
});
My problem is that I've been getting an 401 error, and nothing I do correct this.
I'm local and not using a server.